【问题标题】:how to shift non nan value in multiple columns row wise by group? (2nd)如何按组逐行移动多列中的非南值? (2)
【发布时间】:2023-01-25 13:30:41
【问题描述】:

我已经发布了一个类似的问题,jezrael perfertly 解决了这个问题。 但这次我有相同的数据框,其中有一个名为 label 的新行,如下所示:

A1 A2 A3 A4 A5 A6 label
1 nan 3 7 nan 8 A
nan 5 nan 11 9 nan A
54 6 84 12 3 nan A
10 nan nan 16 nan 45 B
12 93 13 31 5 91 B
73 nan 45 nan nan 9 B

我想根据标签列移动非 nan 值 n 行。

n = 1 的期望输出

A1 A2 A3 A4 A5 A6 label
nan nan nan nan nan nan A
nan nan nan 7 nan nan A
1 5 3 11 9 nan A
nan nan nan nan nan nan B
10 nan nan 16 nan 45 B
12 nan 13 nan nan 91 B

上一篇没有标签栏的解决方案是

df = df.apply(lambda x: x.dropna().shift(1))

所以我试过了

columns = df.drop(columns = ['label']).columns
df[columns] = df.groupby(['label'])[columns].apply(lambda x: x.dropna().shift(1))

它只留下所有列中没有 nan 值的行 我只能尝试使用循环解决方案

for column in columns:
        df[column] = df.groupby(['label'])[column].apply(lambda x: x.dropna().shift(1))

当列数变大时,速度又变慢了。想知道是否有办法使我尝试的解决方案有效。

【问题讨论】:

    标签: python pandas shift


    【解决方案1】:

    让我们用transform代替apply

    df.groupby('label')[columns].transform(lambda s: s.dropna().shift(1))
    

    结果

         A1   A2    A3    A4   A5    A6
    0   NaN  NaN   NaN   NaN  NaN   NaN
    1   NaN  NaN   NaN   7.0  NaN   NaN
    2   1.0  5.0   3.0  11.0  9.0   NaN
    3   NaN  NaN   NaN   NaN  NaN   NaN
    4  10.0  NaN   NaN  16.0  NaN  45.0
    5  12.0  NaN  13.0   NaN  NaN  91.0
    

    一些注意事项:

    • 当使用 groupby apply 时,Transform 将分别对每一列进行操作,而不是对所有列进行操作
    • Transform 也会在丢弃 NaN 后将值广播回原始形状

    【讨论】:

    • 我收到一条错误消息:长度不匹配:预期轴有 108167 个元素,新值有 751665 个元素。这应该可以工作,因为我的 df 的长度是 751665,我需要更深入地了解问题所在。
    • 是的,转换比应用函数更合适,感谢您的回复,我会查看我的代码,看看出了什么问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    相关资源
    最近更新 更多