gpt4 book ai didi

python - 基于列表复制 pandas 数据框中的行并用列表条目填充新列

转载 作者:行者123 更新时间:2023-11-30 22:11:21 24 4
gpt4 key购买 nike

我有一个关于在 pandas 数据框中复制行的问题。我已在列表中的“相关冲击”栏中为每个观察结果分配了相关日期。观察 22 有一个空列表,23 有一个日期的列表,24 有两个日期的列表,25 有三个日期的列表(如“liSTLength”列中所示)。

我的目标是通过以下方式扩展数据框:具有空列表的观测值保留在数据集中一行,而具有 x 个观测值的行被重复 x 次 - 因此,第 22 行和第 23 行应该保留在数据框中一次(22尽管列表为空,并且 23 是因为它有一个相关日期),但第 24 行应该重复一次,因此在数据帧中出现两次,而观察 25 应该被复制两次,因此在数据帧中出现三次。因此,每一行在数据帧中出现的次数应该与它具有相关冲击的次数相同(通过列表长度来衡量)。除了列表长度为 0 的之外,它们仍应保留在数据帧中。

此外,我想创建一个新列“相关冲击”,由每个相关冲击单独填充一次。

这是当前的数据框:

    quarter year    pddate      relevant shocks                                                 listlength
22 1 2012 2012-02-15 [] 0.0
23 4 2011 2011-11-15 [2011-08-18 00:00:00] 1.0
24 3 2011 2011-08-15 [2011-08-18 00:00:00, 2011-09-22 00:00:00] 2.0
25 2 2011 2011-05-13 [2011-08-04 00:00:00, 2011-08-08 00:00:00, 2011-08-10 00:00:00 3.0

新的数据框应有 7 行,如下所示:

    quarter year    pddate      relevant shocks                                                 listlength    relevant shock
22 1 2012 2012-02-15 [] 0.0
23 4 2011 2011-11-15 [2011-08-18 00:00:00] 1.0 2011-08-18 00:00:00
24 3 2011 2011-08-15 [2011-08-18 00:00:00, 2011-09-22 00:00:00] 2.0 2011-08-18 00:00:00
25 3 2011 2011-08-15 [2011-08-18 00:00:00, 2011-09-22 00:00:00] 2.0 2011-09-22 00:00:00
26 2 2011 2011-05-13 [2011-08-04 00:00:00, 2011-08-08 00:00:00, 2011-08-10 00:00:00 3.0 2011-08-04 00:00:00
27 2 2011 2011-05-13 [2011-08-04 00:00:00, 2011-08-08 00:00:00, 2011-08-10 00:00:00 3.0 2011-08-08 00:00:00
28 2 2011 2011-05-13 [2011-08-04 00:00:00, 2011-08-08 00:00:00, 2011-08-10 00:00:00 3.0 2011-08-10 00:00:00

所以基本的想法是添加新列“相关冲击”,遍历每一行,如果“相关冲击”中有空列表,则保持不变,如果“相关冲击”中有一个日期,也保持不变相关冲击”,但用该列表条目填充新列“相关冲击”,如果“相关冲击”中有两个列表条目,则复制它,并用两个列表条目之一填充每行中的“相关冲击”列,分别等等。

这可以用 Python 实现吗?

最佳答案

EDIT for pandas version >= 0.25,一种新方法 explode会很容易地完成这项工作:

#first create a copy of the column
df['relevant shock'] = df['relevant shocks']
#explode the new column
df = df.explode('relevant shock').fillna('')
print (df)
#same result than the one below

旧答案

在“相关冲击”列中,您可以使用 applypd.Seriesstack 为每个日期创建一行,例如如:

df['relevant shocks'].apply(pd.Series).stack()
Out[448]:
23 0 2011-08-18 00:00:00
24 0 2011-08-18 00:00:00
1 2011-09-22 00:00:00
25 0 2011-08-04 00:00:00
1 2011-08-08 00:00:00
2 2011-08-10 00:00:00
dtype: object

我知道缺少一个空的,但是在您使用reset_index将结果join到您的df之后,fillna删除 额外的列。使用像这样的 df:

df = pd.DataFrame({'quarter':[1,2,3,4],
'relevant shocks':[[],['2011-08-18 00:00:00'],
['2011-08-18 00:00:00', '2011-09-22 00:00:00'],
['2011-08-04 00:00:00', '2011-08-08 00:00:00', '2011-08-10 00:00:00']]},
index=[22,23,24,25])

然后你就可以:

df = (df.join(df['relevant shocks'].apply(pd.Series).stack()
.reset_index(1,name='relevant shock'))
.fillna('').drop('level_1',1))

你会得到:

    quarter                                    relevant shocks  \
22 1 []
23 2 [2011-08-18 00:00:00]
24 3 [2011-08-18 00:00:00, 2011-09-22 00:00:00]
24 3 [2011-08-18 00:00:00, 2011-09-22 00:00:00]
25 4 [2011-08-04 00:00:00, 2011-08-08 00:00:00, 201...
25 4 [2011-08-04 00:00:00, 2011-08-08 00:00:00, 201...
25 4 [2011-08-04 00:00:00, 2011-08-08 00:00:00, 201...

relevant shock
22
23 2011-08-18 00:00:00
24 2011-08-18 00:00:00
24 2011-09-22 00:00:00
25 2011-08-04 00:00:00
25 2011-08-08 00:00:00
25 2011-08-10 00:00:00

编辑:似乎对于真实数据,空列表发生了错误,因此要解决它并在最后reset_index:

df = (df.join(df.loc[df['relevant shocks'].str.len() > 0, 'relevant shocks']
.apply(pd.Series).stack().reset_index(1,name='relevant shock'))
.fillna('').drop('level_1',1).reset_index(drop=True))

关于python - 基于列表复制 pandas 数据框中的行并用列表条目填充新列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51443124/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com