Python 创建其他记录并填写熊猫
我有一个熊猫数据框,看起来像这样:Python 创建其他记录并填写熊猫,python,pandas,Python,Pandas,我有一个熊猫数据框,看起来像这样: +----+-------+-----+ | | name | max | +----+-------+-----+ | 0 | a | 1 | | 1 | b | 2 | | 2 | c | 2 | | 3 | d | 4 | | 4 | e | 1 | +----+-------+-----+ +----+-------+------+--------+ | | name
+----+-------+-----+
| | name | max |
+----+-------+-----+
| 0 | a | 1 |
| 1 | b | 2 |
| 2 | c | 2 |
| 3 | d | 4 |
| 4 | e | 1 |
+----+-------+-----+
+----+-------+------+--------+
| | name | max | number |
+----+-------+------+--------+
| 0 | a | 1 | 1 |
| 1 | b | 2 | 2 |
| 2 | b | 2 | 1 |
| 3 | c | 2 | 2 |
| 4 | c | 2 | 1 |
| 5 | d | 4 | 4 |
| 6 | d | 4 | 3 |
| 7 | d | 4 | 2 |
| 8 | d | 4 | 1 |
| 9 | e | 1 | 1 |
+----+-------+------+--------+
列name
表示项目名称,而列max
表示名称所属的最大组号。通过提供这些数据的方式,项目不仅属于该最大组,而且还属于小于该数字的每个组
我想“分解”这个数据帧,为每个名称创建额外的记录,并在一个新列中倒数max到值1
最终,我希望我的新数据框架如下所示:
+----+-------+-----+
| | name | max |
+----+-------+-----+
| 0 | a | 1 |
| 1 | b | 2 |
| 2 | c | 2 |
| 3 | d | 4 |
| 4 | e | 1 |
+----+-------+-----+
+----+-------+------+--------+
| | name | max | number |
+----+-------+------+--------+
| 0 | a | 1 | 1 |
| 1 | b | 2 | 2 |
| 2 | b | 2 | 1 |
| 3 | c | 2 | 2 |
| 4 | c | 2 | 1 |
| 5 | d | 4 | 4 |
| 6 | d | 4 | 3 |
| 7 | d | 4 | 2 |
| 8 | d | 4 | 1 |
| 9 | e | 1 | 1 |
+----+-------+------+--------+
我正在考虑使用函数df.ffill()
,但这只会填充NaN
,我需要首先创建NaN
行。我也在考虑使用df.groupby()
,但我也不确定这是否是正确的方向
我可以用嵌套的
for循环
这样的方法来实现这一点,但我不希望迭代数据帧 您可以使用填充行的“max”列w.r.t的累积和重新索引数据帧,在“name”列中用“bfill”填充行,并在“max”列中摸索减量顺序
df.index = df['max'].cumsum()-1
df = df.reindex(pd.RangeIndex(df.index.max() + 1)).bfill()
df = df.groupby(['name']).apply(lambda x: x['max'] - np.arange(len(x))).reset_index().drop(['level_1'],axis=1)
输出:
我的变体是:
df2 = df.reindex(df.index.repeat(df["max"])).reset_index(drop=True)
df2["number"] = df2.groupby("name").cumcount(ascending=False) + 1
给
In [137]: df2
Out[137]:
name max number
0 a 1 1
1 b 2 2
2 b 2 1
3 c 2 2
4 c 2 1
5 d 4 4
6 d 4 3
7 d 4 2
8 d 4 1
9 e 1 1
它确实假设原始索引是唯一的,以使重复操作简洁。如果需要,我们可以用
df2 = df.iloc[np.repeat(range(len(df)), df["max"])].reset_index(drop=True)
或者别的什么。你以后会担心另一个同名的团队吗?你能要一个b c d e b吗?在这种情况下不行。实际上,
name
实际上是索引,但在这一步之前我使用了reset\u index()
。