根据条件融合pandas数据框

3
我有一个具有以下格式的数据框架:
时间戳 ID Col1 Col2 Col3 Col4 有用的列
16/11/2021 1 0.2 0.1 Col3
17/11/2021 1 0.3 0.8 Col3
17/11/2021 2 10 Col2
17/11/2021 3 0.1 2 Col4
我想将其"融合"成以下格式:
时间戳 ID 列名
16/11/2021 1 Col3 0.1
17/11/2021 1 Col3 0.8
17/11/2021 2 Col2 10
17/11/2021 3 Col4 2
我该如何操作?
输入为数据框:
from numpy import nan
df = pd.DataFrame({'timestamp': ['16/11/2021', '17/11/2021', '17/11/2021', '17/11/2021'],
                   'ID': [1, 1, 2, 3],
                   'Col1': [0.2, 0.3, nan, nan],
                   'Col2': [nan, nan, 10.0, nan],
                   'Col3': [0.1, 0.8, nan, 0.1],
                   'Col4': [nan, nan, nan, 2.0],
                   'UsefulCol': ['Col3', 'Col3', 'Col2', 'Col4']})
2个回答

1

首先尝试使用有用的值创建一列:

df['Value'] = df.apply(lambda x: x[x.UsefulCol], axis=1)

timestamp   ID    Col1    Col2    Col3    Col4    UsefulCol    Value
16/11/2021  1     0.2             0.1             Col3         0.1
17/11/2021  1     0.3             0.8             Col3         0.8
17/11/2021  2              10                     Col2         10
17/11/2021  3                     0.1     2       Col4         2

然后,您可以删除要融合的列:

df.drop(['Col1', 'Col2', 'Col3', 'Col4], axis=1, inplace=True)

注意:本文为技术文章,翻译中使用了专业术语。
timestamp   ID    UsefulCol    Value
16/11/2021  1     Col3         0.1
17/11/2021  1     Col3         0.8
17/11/2021  2     Col2         10
17/11/2021  3     Col4         2

如果需要,可以重命名列:

df.rename({'UsefulCol':'Col'}, axis=1, inplace=True)

或者

df.columns = ['timestamp', 'ID', 'Col', 'Value']


-1
这里是一个使用一点点numpy的矢量解决方案:
import numpy as np

# select columns to pseudo-melt (this could be a manual list cols=['A', 'B', 'C'])
cols = df.filter(regex='^Col').columns

# slice the needed values (they will be on the diagonal) and keep only diagonal
df['Value'] = np.diag(df.filter(regex='^Col').loc[:, df['UsefulCol']].values)

# drop old columns
new_df = df.drop(columns=cols)

输出:

    timestamp  ID UsefulCol     Value
0  16/11/2021   1      Col3    0.1000
1  17/11/2021   1      Col3    0.8000
2  17/11/2021   2      Col2   10.0000
3  17/11/2021   3      Col4    2.0000

谢谢您的建议。我很喜欢这个想法,但不幸的是,在我的情况下它无法工作。我遇到了错误:“无法为形状为(129710,129710)和数据类型float64的数组分配125. GiB”。在我的情况下,创建一个巨大的方阵来取对角线是无效的。再次感谢。 - ML learner
@MLlearner 是的,这不适用于非常大的数据集(不确定这是否是负投票的原因)。 - mozway

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接