【问题标题】:How to add a column to a Pandas dataframe made of arrays of the n-preceding values of another column?如何将一列添加到由另一列的前 n 个值的数组组成的 Pandas 数据框中?
【发布时间】:2023-03-29 08:27:01
【问题描述】:

我是 python 和 pandas 的新手。我不知道如何以优雅的方式解决以下问题

假设我们有一个简单的 pandas 数据框。

import numpy as np
import pandas as pd
from pandas import DataFrame, Series
df = pd.DataFrame(np.arange(0,60,10), columns=['Value'])

现在设置一个变量,例如:

n = 3

目标是向 df 添加一列由 n-preceding 值的数组组成,如下所示:

下一步可能是将 NaN 设置为零。

有没有聪明的方法来做到这一点?

提前感谢您的帮助,

吉尔伯特

【问题讨论】:

  • 您已经可以生成ArrayValues 列了吗?
  • 没有。目标是一个简单的命令/函数来生成列,如果可能的话,以矢量化的方式。
  • 下一次,添加代码而不是你的 pandas 数据框的图片;)
  • 好的,谢谢你的建议
  • @Afke 我不认为代码在这里会有所帮助,这张图片真的让问题很清楚

标签: python arrays pandas dataframe


【解决方案1】:

我们可以使用df.shift 生成偏移列和列表推导将它们组合在一起,然后mapdataframe 生成listslist。但是,生成的listslist 需要先进行转置,然后再将其分配给原始df,以便我们拥有与正确行对应的值列表。

df["b"] =np.array(map(list,[df["a"].shift(x) for x in range(1,4)])).T.tolist()

输入:

   a
0  1
1  2
2  3
3  4

输出:

   a                b
0  1  [nan, nan, nan]
1  2  [1.0, nan, nan]
2  3  [2.0, 1.0, nan]
3  4  [3.0, 2.0, 1.0]

【讨论】:

  • 谢谢@Yarnspinner,我试过你的代码,但我得到:<map object at 0x111bafda0>b 的值。你的代码启发了我。
  • 我将您的代码更改为df["b"] = np.array(list(map(list,[df["a"].shift(x) for x in range(1,4)]))).T.tolist() 添加np.array(list(map。现在它完美地工作了。谢谢@Yarnspinner。
【解决方案2】:

这有点麻烦,但以下工作:

In [63]:
def func(x):
    return pd.Series(df['Value'], index=np.arange(x.name-3,x.name)).values.tolist()
df['ArrayValues'] = df[['Value']].apply(lambda x: func(x), axis=1)
df
​
Out[63]:
   Value       ArrayValues
0      0   [nan, nan, nan]
1     10   [nan, nan, 0.0]
2     20  [nan, 0.0, 10.0]
3     30       [0, 10, 20]
4     40      [10, 20, 30]
5     50      [20, 30, 40]

所以首先我们使用[[]] 对df 进行双下标,这样我们就可以将单列强制转换为df,这样我们就可以调用apply 并使用参数axis=1apply 我们的func 行,这是必需的,因为我们希望使用通过name 属性访问的当前行索引值来根据索引范围返回重新索引的Series,因为索引值不存在它会为索引创建NaN 值不存在的行,最后我们需要通过返回一个 numpy 数组来匿名化数据并将其转换为列表,这样我们就不会尝试在 Series 索引上对齐

编辑

如果我们将开始/停止参数交换为 np.arange 并使用负步骤,那么您将获得所需的顺序:

In [70]:
def func(x):
    return pd.Series(df['Value'], index=np.arange(x.name-1,x.name-4,-1)).values.tolist()
df['ArrayValues'] = df[['Value']].apply(lambda x: func(x), axis=1)
df
​
Out[70]:
   Value       ArrayValues
0      0   [nan, nan, nan]
1     10   [0.0, nan, nan]
2     20  [10.0, 0.0, nan]
3     30       [20, 10, 0]
4     40      [30, 20, 10]
5     50      [40, 30, 20]

【讨论】:

  • 谢谢@EdChum 我试过你的代码,我得到了同样的结果。现在我必须做一个小改动才能按要求排序数组:例如 [40, 30, 20] 而不是 [20, 30, 40]
  • 所以您希望它按值排序,或者您只是对倒序感兴趣?
  • 例如第 5 行必须包含一个由 4、3、2 行值按此顺序组成的数组。
  • 如果我的回答解决了您的问题,那么您可以接受,我的回答左上角会有一个空勾
猜你喜欢
  • 2022-01-07
  • 2016-03-28
  • 2022-06-11
  • 2014-11-02
  • 2016-02-03
  • 1970-01-01
  • 1970-01-01
  • 2020-11-24
  • 2021-06-07
相关资源
最近更新 更多