【问题标题】:generate lines with all unique values of given column for each group为每个组生成具有给定列的所有唯一值的行
【发布时间】:2018-03-30 14:48:37
【问题描述】:
df = pd.DataFrame({'timePoint': [1,1,1,1,2,2,2,2,3,3,3,3],
                        'item': [1,2,3,4,3,4,5,6,1,3,7,2],
                       'value': [2,4,7,6,5,9,3,2,4,3,1,5]})

>>> df
    item  timePoint  value
0      1          1      2
1      2          1      4
2      3          1      7
3      4          1      6
4      3          2      5
5      4          2      9
6      5          2      3
7      6          2      2
8      1          3      4
9      3          3      3
10     7          3      1
11     2          3      5

在这个df 中,并不是每个item 都出现在每个timePoint 上。我想在每个timePoint 上都有所有唯一的items,而这些新插入的items 应该有:

(i) NaN value 如果他们没有出现在之前的timePoint 中,或者
(ii) 如果有,他们会得到最近的value

所需的输出应如下所示(带有标签的行是插入的行)。

>>> dfx
    item  timePoint  value
0      1          1    2.0
3      1          2    2.0 #
8      1          3    4.0
1      2          1    4.0
4      2          2    4.0 #
11     2          3    5.0
2      3          1    7.0
4      3          2    5.0
9      3          3    3.0
3      4          1    6.0
5      4          2    9.0
6      4          3    9.0 #
0      5          1    NaN #
6      5          2    3.0 
7      5          3    3.0 #
1      6          1    NaN #
7      6          2    2.0 
8      6          3    2.0 #
2      7          1    NaN #
5      7          2    NaN #
10     7          3    1.0

例如,item 1timePoint 2 得到一个4.0,因为这就是它有一个timePoint 1item 6 在@2@34 得到一个@987654 987654343@1,因为前面没有value

现在,我知道如果我设法在每个 timePoint group 中插入每个唯一 item 缺失的所有行,即达到这一点:

>>> dfx
    item  timePoint  value
0      1          1    2.0
1      2          1    4.0
2      3          1    7.0
3      4          1    6.0
4      3          2    5.0
5      4          2    9.0
6      5          2    3.0
7      6          2    2.0
8      1          3    4.0
9      3          3    3.0
10     7          3    1.0
11     2          3    5.0
0      5          1    NaN
1      6          1    NaN
2      7          1    NaN
3      1          2    NaN
4      2          2    NaN
5      7          2    NaN
6      4          3    NaN
7      5          3    NaN
8      6          3    NaN

那我可以做:

dfx.sort_values(by = ['item', 'timePoint'],
                                inplace = True,
                                ascending = [True, True])
dfx['value'] = dfx.groupby('item')['value'].fillna(method='ffill')

这将返回所需的输出。

但是如何将所有 df.item.unique() items 添加为每个 timePoint group 中缺少的行?

另外,如果你有一个更有效的解决方案可以从头开始建议,那么请务必成为我的客人。

【问题讨论】:

    标签: pandas pandas-groupby


    【解决方案1】:

    使用pd.MultiIndex.from_productlevelsreindex

    d = df.set_index(['item', 'timePoint'])
    d.reindex(
        pd.MultiIndex.from_product(d.index.levels, names=d.index.names)
    ).groupby(level='item').ffill().reset_index()
    
        item  timePoint  value
    0      1          1    2.0
    1      1          2    2.0
    2      1          3    4.0
    3      2          1    4.0
    4      2          2    4.0
    5      2          3    5.0
    6      3          1    7.0
    7      3          2    5.0
    8      3          3    3.0
    9      4          1    6.0
    10     4          2    9.0
    11     4          3    9.0
    12     5          1    NaN
    13     5          2    3.0
    14     5          3    3.0
    15     6          1    NaN
    16     6          2    2.0
    17     6          3    2.0
    18     7          1    NaN
    19     7          2    NaN
    20     7          3    1.0
    

    【讨论】:

    • 感谢您的回答。在pandas'0.19.2',运行第二行时,我得到KeyError: 'item'
    • 那你需要groupby(level='item')
    • 谢谢。然后我将更改为接受此答案,因为它也可以与多个值列一起使用。您能否使用groupby(level='item') 更新您的答案,以便它适用于所有人。这是与pandas 版本相关的问题还是其他问题?
    • 是的,是版本问题。较新的版本允许引用索引级别名称。
    【解决方案2】:

    我认为stackunstack 将实现格式,然后我们使用groupby ffill 向前填充nan 值

    s=df.set_index(['item','timePoint']).value.unstack().stack(dropna=False)
    s.groupby(level=0).ffill().reset_index()
    Out[508]: 
        item  timePoint    0
    0      1          1  2.0
    1      1          2  2.0
    2      1          3  4.0
    3      2          1  4.0
    4      2          2  4.0
    5      2          3  5.0
    6      3          1  7.0
    7      3          2  5.0
    8      3          3  3.0
    9      4          1  6.0
    10     4          2  9.0
    11     4          3  9.0
    12     5          1  NaN
    13     5          2  3.0
    14     5          3  3.0
    15     6          1  NaN
    16     6          2  2.0
    17     6          3  2.0
    18     7          1  NaN
    19     7          2  NaN
    20     7          3  1.0
    

    【讨论】:

    • 感谢您的回答!请补充问题。如果我在原始df 中有多个value 列(例如value1value2 ..),是否有任何方法可以遵循这种方法,或者我是否必须为每个列重复该过程value 列然后合并得到的dfs?
    • @Tony 你可以查看 Pir 的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    相关资源
    最近更新 更多