基于条件加法转换数据集-复杂

时间:2020-10-27 03:42:32

标签: python pandas

我想将以下数据从df1转换为df2:

df1:

   ID  a  b  c  d  a-d  c-d  a-c-d
0   1  0  0  0  0    0    0      1
1   2  0  0  1  0    1    0      0
2   3  0  1  0  0    0    1      0
3   4  0  0  0  0    1    0      1
4   5  0  0  1  1    0    0      0

df2是:

   ID  a  b  c  d
0   1  1  0  1  1
1   2  1  0  1  1
2   3  0  1  1  1
3   4  2  0  1  2
4   5  0  0  1  1

基本上,我想从列名中出现字母“ a”的所有列中获取“ a”的总值。例如。在df1的第4行中,有2个列名称,其中出现字母“ a”。如果将第4行中的所有“ a”加起来,那么总共会有2个a。我想要新数据集(df2)中的一列苹果。请注意,“ a-c-d”的1为每个“ a”,“ b”,“ c”的1。

4 个答案:

答案 0 :(得分:1)

如果您提前知道了唯一类别(例如[“ a”,“ b”,“ c”,“ d”]),则可以采取一些捷径,并依靠df.filter来收集所有带有该字母的列,然后使用.sum(axis=1)对这些列求和以创建期望的摘要值:

data = {"ID": df["ID"]}

for letter in ["a", "b", "c", "d"]:
    data[letter] = df.filter(like=letter).sum(axis=1)
    
final_df = pd.DataFrame(data)

print(final_df)
   ID  a  b  c  d
0   1  1  0  1  1
1   2  1  0  1  1
2   3  0  1  1  1
3   4  2  0  1  2
4   5  0  0  1  1

答案 1 :(得分:0)

让我们尝试melt堆叠列名,然后依次str.splitexplode拆分a,b,c,d并复制数据:

(df1.melt('ID', var_name='col')
    .assign(col=lambda x: x['col'].str.split('-'))
    .explode('col')
    .pivot_table(index='ID',columns='col', 
                 values='value', aggfunc='sum')
    .reset_index()
)

输出:

col  ID  a  b  c  d
0     1  1  0  1  1
1     2  1  0  1  1
2     3  0  1  1  1
3     4  2  0  1  2
4     5  0  0  1  1

答案 2 :(得分:0)

类似split然后是explodegroupbysum

out = df.T.reset_index().assign(index=lambda x : x['index'].str.split('-')).explode('index').\
       groupby('index').sum().T
Out[102]: 
index  ID  a  b  c  d
0       1  1  0  1  1
1       2  1  0  1  1
2       3  0  1  1  1
3       4  2  0  1  2
4       5  0  0  1  1

答案 3 :(得分:0)

好吧,只是为了在这里完成答案,一种更手动的方法如下:

df1.loc[:, 'a'] = df1.loc[:, 'a'] + df1.loc[:, 'a-d'] + df1.loc[:, 'a-c-d']  
df1.loc[:, 'c'] = df1.loc[:, 'c'] + df1.loc[:, 'c-d'] + df1.loc[:, 'a-c-d']
df1.loc[:, 'd'] = df1.loc[:, 'd'] + df1.loc[:, 'a-d'] + df1.loc[:, 'c-d'] + df1.loc[:, 'a-c-d']

输出:

col  ID  a  b  c  d
0     1  1  0  1  1
1     2  1  0  1  1
2     3  0  1  1  1
3     4  2  0  1  2
4     5  0  0  1  1