python - 根据列表复制熊猫数据框中的行并用列表条目填充新列
问题描述
我有一个关于在熊猫数据框中复制行的问题。我已经为列表中“相关冲击”一栏中的每个观察分配了相关日期。观察 22 有一个空列表,23 有一个日期的列表,24 有两个日期的列表和 25 有三个日期的列表(如“listlength”列所示)。
我的目标是以如下方式扩展数据框:具有空列表的观察结果保留在数据集中一行,而具有 x 观察结果的行被重复 x 次 - 因此,第 22 行和第 23 行应该保留在数据框中一次(22 尽管为空列表和 23,因为它有一个相关日期),第 24 行应该被复制一次,因此在数据框中两次,观察 25 应该被复制两次,因此在数据框中三次。因此,每一行在数据框中的次数应与它具有相关冲击的次数一样多(由 listlength 衡量)。除了列表长度为 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 实现吗?
解决方案
编辑熊猫版本> = 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
旧答案
从“相关冲击”列中,您可以使用apply
,pd.Series
并stack
为每个日期创建一行,例如:
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
我知道一个空的丢失了,但是在你使用a和额外的列之后你join
的结果。像这样:df
reset_index
fillna
drop
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 - 邻里搜索
- java - 将 gradle 插件发布到 jcenter 失败
- python - Jinja2 包含批处理过滤器
- html - 菜单下拉菜单向右对齐
- angular - Using object as as a parameter of get method of Angular
- parameters - 在 Lua 中使用 `arg` 作为参数名称有什么副作用吗?
- reactjs - 如何避免使用 Typescript 在 React 构造函数中重新声明道具类型
- ios - 标签栏控制器显示最后推送的控制器 - swift 4
- sql - cx_Oracle.DatabaseError: ORA-00904: "DATETIME"."DATETIME": 标识符无效
- discord.js - 如何检测到用户从一个语音通道更改为另一个语音通道?