【问题标题】:Create additional records and fill forward with pandas创建其他记录并用 pandas 填写
【发布时间】:2018-09-16 17:07:32
【问题描述】:

我有一个看起来像这样的 pandas 数据框:

+----+-------+-----+
|    | name  | max |
+----+-------+-----+
| 0  | a     | 1   |
| 1  | b     | 2   |
| 2  | c     | 2   |
| 3  | d     | 4   |
| 4  | e     | 1   |
+----+-------+-----+

name 列表示项目名称,max 列表示该名称所属的最大组数。通过提供此数据的方式,一个项目不仅属于该最大组,而且还属于小于该数量的每个组。

我想“分解”这个数据框以为每个名称创建额外的记录,并在新列中将最大值倒计时到值 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-loop 之类的东西来做到这一点,但我宁愿不遍历数据框。

【问题讨论】:

  • 您以后会不会担心另一个同名的组?你能有一个 b c d e b 吗?
  • 没有这种情况。其实name其实就是索引,不过在这一步之前我用的是reset_index()

标签: python pandas


【解决方案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)

什么的。

【讨论】:

    【解决方案2】:

    您可以使用估算行的“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)
    

    输出:

      name  max
    0   a   1.0
    1   b   2.0
    2   b   1.0
    3   c   2.0
    4   c   1.0
    5   d   4.0
    6   d   3.0
    7   d   2.0
    8   d   1.0
    9   e   1.0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 2017-06-19
      相关资源
      最近更新 更多