【问题标题】:how to shift columns in pandas DataFrame dynamically and independently?如何动态且独立地移动 pandas DataFrame 中的列?
【发布时间】:2020-03-06 14:31:41
【问题描述】:

我希望实现的是能够标准化我的值,以便它们都从任意零天开始。想象一下下面的 DataFrame:

df = pd.DataFrame(np.array([[1, 0, 0], [4, 5, 0], [7, 8, 9], [7, 8, 9], [4, 5, 0], [7, 8, 9]]), 
              columns=['a', 'b', 'c'], 
              index = ['1/1/2000', '1/1/2001', '1/1/2002', '1/1/2003', '1/1/2004', '1/1/2005'])

结果如下:

            a   b   c
1/1/2000    1   0   0
1/1/2001    4   5   0
1/1/2002    7   8   9
1/1/2003    7   8   9
1/1/2004    4   5   0
1/1/2005    7   8   9    

我想要实现的是在每列中找到第一个非零值,并将该列中的值移动到索引零。所以最终的 dataFrame 看起来像这样:

            a   b   c
1/1/2000    1   5   9
1/1/2001    4   8   9
1/1/2002    7   8   0
1/1/2003    7   5   9
1/1/2004    4   8   0
1/1/2005    7   0   0 

我尝试使用轮班,我可以使用这样的东西:

df.b = df.b.shift(periods = -1, fill_value = 0)

但目前我不知道任何不使用 for 循环等对 pandas 友好的方法。

欣赏是否有人可以帮助最好地找到第一个非零值,然后将这些值正确地移动到索引零。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    首先通过比较不等于DataFrame.ne 获得班次数,然后通过DataFrame.cumsum 相加累积和,比较0 和最后计数Trues 通过sum。然后将 DataFrame.apply 与 lambda 函数一起使用,并为班次选择 Series 的值:

    s = df.ne(0).cumsum().eq(0).sum()
    df = df.apply(lambda x: x.shift(periods = -s[x.name], fill_value = 0))
    print (df)
              a  b  c
    1/1/2000  1  5  9
    1/1/2001  4  8  9
    1/1/2002  7  8  0
    1/1/2003  7  5  9
    1/1/2004  4  8  0
    1/1/2005  7  0  0
    

    【讨论】:

    • 感谢您非常聪明的回答,您能解释一下为什么第二行有效吗?我是 pandas 的新手,我将当前的项目用作学习机会。我对 -s[x.name] 特别感到困惑,我知道 s 是一个 DataSeries,但我无法理解 x 指的是什么以及 x.name 如何对 s 有意义,再次感谢。
    猜你喜欢
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多