我正在尝试解压缩包含具有值列表的列的数据集。每个列表中的第一个位置表示在"日期"中的日期所采取的测量。柱。下一个位置是前一天的测量,依此类推(最多30天)。这些列表的长度并不相同,但count_users中列表的长度将等于count_samples中的长度。
目标是获取数据,使每个日期每个名称有1行,每行中有count_users和count_samples的单个度量。
换句话说,阵列的位置需要映射到特定的日期,每个名称的测量值应该相加每天。
原始数据如下所示:
Name Date count_users count_samples
A 2017-10-20 [0,0,1,2,2,4] [1,2,1,1,1,3]
A 2017-10-18 [5,2,0,0,0,0] [1,2,1,1,1,3]
B 2017-11-24 [0,0,0,0,4] [1,1,1,1,3]
C 2017-09-02 [] []
D 2017-10-30 [0,0,2,4] [1,2,1,1]
结果看起来应该是这样的:
Name Date count_users count_samples
A 2017-10-20 0 1
A 2017-10-19 0 2
A 2017-10-18 6 2
A 2017-10-17 4 3
A 2017-10-16 2 2
A 2017-10-15 4 4
A 2017-10-14 0 1
A 2017-10-13 0 3
有人可以推荐一个解决方案吗?
更新dict风格的数据:
{'Date': {0: Timestamp('2017-10-20 00:00:00'),
1: Timestamp('2017-10-18 00:00:00'),
2: Timestamp('2017-11-24 00:00:00'),
3: Timestamp('2017-09-02 00:00:00'),
4: Timestamp('2017-10-30 00:00:00')},
'Name': {0: 'A', 1: 'A', 2: 'B', 3: 'C', 4: 'D'},
'count_samples': {0: [1, 2, 1, 1, 1, 3],
1: [1, 2, 1, 1, 1, 3],
2: [1, 1, 1, 1, 3],
3: [],
4: [1, 2, 1, 1]},
'count_users': {0: [0, 0, 1, 2, 2, 4],
1: [5, 2, 0, 0, 0, 0],
2: [0, 0, 0, 0, 4],
3: [],
4: [0, 0, 2, 4]}}
答案 0 :(得分:2)
有点难以得到它
New_df=pd.DataFrame({'Date':np.concatenate(np.array([pd.date_range(end=x,periods=y,freq='D')[::-1] for x,y in zip(df.Date,df.count_samples.apply(len))])),
'Name':df.Name.repeat(df.count_samples.apply(len)),
'count_samples':np.concatenate(df.count_samples.values),
'count_users':np.concatenate(df.count_users.values)})
New_df.groupby(['Name','Date'],as_index=False).sum().sort_values(['Name','Date'],ascending=[True,False])
Out[458]:
Name Date count_samples count_users
7 A 2017-10-20 1.0 0.0
6 A 2017-10-19 2.0 0.0
5 A 2017-10-18 2.0 6.0
4 A 2017-10-17 3.0 4.0
3 A 2017-10-16 2.0 2.0
2 A 2017-10-15 4.0 4.0
1 A 2017-10-14 1.0 0.0
0 A 2017-10-13 3.0 0.0
12 B 2017-11-24 1.0 0.0
11 B 2017-11-23 1.0 0.0
10 B 2017-11-22 1.0 0.0
9 B 2017-11-21 1.0 0.0
8 B 2017-11-20 3.0 4.0
16 D 2017-10-30 1.0 0.0
15 D 2017-10-29 2.0 0.0
14 D 2017-10-28 1.0 2.0
13 D 2017-10-27 1.0 4.0
答案 1 :(得分:1)
你可以试试这个。
pd.concat
粘合。 groupby
对同一日期的值求和。 注意,在此示例中,count_users
和count_samples
是字符串,我使用literal_eval
将其转换为列表。如果已经有一个列表,你应该摆脱literal_eval
。
from ast import literal_eval
def unpack(row):
l = len(literal_eval(row.count_users))
date_index = pd.date_range(end=row.Date, periods=l)
date_index = date_index[::-1] # reverse it
df = pd.DataFrame({"Name": [row.Name for _ in range(l)],
"count_users": literal_eval(row.count_users),
"count_samples": literal_eval(row.count_samples)})
df.set_index(date_index, inplace=True)
return df
df_temp = pd.concat([unpack(row) for idx, row in df.iterrows()])
df_wanted = df_temp.reset_index().groupby(["index", "Name"]).sum()
结果
对于pd.date_range
,您可以告诉它end=LAST_DATE
的最后日期,并告诉它您需要从LAST_DATE
向后period=LENGTH_DATES_YOU_NEED
多少天。