我有一个如下所示的数据框,其中第一列包含日期,其他列包含这些日期的数据:
date k1-v1 k1-v2 k2-v1 k2-v2 k1k3-v1 k1k3-v2 k4-v1 k4-v2
0 2021-01-05 2.0 7.0 NaN NaN NaN NaN 9.0 6.0
1 2021-01-31 NaN NaN 8.0 5.0 NaN NaN 7.0 6.0
2 2021-02-15 9.0 5.0 NaN 3.0 4.0 NaN NaN NaN
3 2021-02-28 NaN 9.0 0.0 1.0 NaN NaN 8.0 8.0
4 2021-03-20 7.0 NaN NaN NaN NaN NaN NaN NaN
5 2021-03-31 NaN NaN 8.0 NaN 3.0 NaN 8.0 0.0
6 2021-04-10 NaN NaN 7.0 6.0 NaN NaN NaN 9.0
7 2021-04-30 NaN 6.0 NaN NaN NaN NaN 1.0 NaN
8 2021-05-14 8.0 NaN 3.0 3.0 4.0 NaN NaN NaN
9 2021-05-31 NaN NaN 2.0 1.0 NaN NaN NaN NaN
列总是成对的:(
k1-v1
,
k1-v2
)
(
k2-v1
,
k2-v2
)
(
k1k3-v1
,
k1k3-v2
)
等N对。但这对列并不总是按此顺序排列。因此k1-v1后面不一定只跟k1-v2,但在数据框的某个地方会有k1-v2列。为了简单起见,我将它们并排展示
我需要在每对列中查找上次有效数据,并将其汇总如下:
keys v1-last v2-last
0 k1 2021-05-14 2021-04-30
1 k2 2021-05-31 2021-05-31
2 k1k3 2021-05-14 NaN
3 k4 2021-04-30 2021-04-10
因此,对于{v1-last
和v2-last
将相应地填充k1,其他列也是如此
目前,我正在按照以下方式进行操作,这在较大的数据集上不是很有效:
df.set_index('date', inplace=True)
unique_cols = set([col[0] for col in df.columns.str.split('-')])
summarized_data = []
for col in unique_cols:
pair_df = df.loc[:,[col+'-v1',col+'-v2']].dropna(how='all')
v1_last_valid = pair_df.iloc[:,0].last_valid_index()
v2_last_valid = pair_df.iloc[:,1].last_valid_index()
summarized_data.append([col, v1_last_valid, v2_last_valid])
summarized_df = pd.DataFrame(summarized_data, columns=['keys','v1-last','v2-last'])
这一方法目前还可以使用,并给出了预期的结果,但在大数据集上运行时需要相当长的时间。是否可以避免循环,并以不同且高效的方式进行
我们可以反转列的名称并使用
pd.wide_to_long
,其中stubnames将是v_j
,identifier将是date
,我们在结果中将k*
称为keys
。然后我们可以按keys
分组,并使用DataFrame.last_valid_index
进行聚合:得到
要使
v_j
的存根名称更通用,请执行以下操作:重命名列,然后使用
wide_to_long
重新构造数据帧Stack
删除NAN
。然后使用groupby-agg
提取最后一个值输出:
溶液
解释
将dataframe的索引设置为
date
和stack
以重新形状重置索引并删除
level_1
中具有重复值的行Split
使用level_1
列中的字符串创建另外两列keys
和val
Pivot
数据帧,用于重新形状并向列名添加后缀-last
相关问题 更多 >
编程相关推荐