复制&根据列条件修改pandas中的行

时间:2016-12-08 15:46:18

标签: python pandas dataframe

作为分类问题的一部分,我处理包含多个标签列的DataFrame。

我的数据框架是这种形式:

df = pd.DataFrame([['a', 1, 1],
                   ['b', 1, 0],
                   ['c', 0, 0]] , columns=['col1', 'label1', 'label2'])

>>>   col1  label1  label2
    0    a       1       1
    1    b       1       0
    2    c       0       0

由于我不希望每行有多个真正的标签,我想只复制那些行并按如下方式规范这个条件:

>>>   col1  label1  label2
    0    a       1       0 # Modified original row
    1    a       0       1 # Duplicated & modified row
    2    b       1       0
    3    c       0       0

只有值“a”的行被重复/正则化

目前我在for循环中执行此操作,复制第二个DataFrame中的行,附加它并删除所有“无效”行。

有没有更清洁/有效的方法来做到这一点?

5 个答案:

答案 0 :(得分:1)

>>> cols = [x for x in df.columns is x != 'col1']
>>> res = pd.concat([df[['col1', x]] for x in cols])
>>> res = res.drop_duplicates()
>>> res.fillna(0, inplace=True)
>>> res.sort_values(by='col1', inplace=True)
>>> res.reset_index(drop=True, inplace=True)
>>> res
  col1  label1  label2
0    a       1       0
1    a       0       1
2    b       1       0
3    b       0       0
4    c       0       0

答案 1 :(得分:1)

您也可以按照以下方式使用df.iterrows()

for index, row in df.iterrows():
    if row[1]+row[2]==2:
        df = pd.concat((df, pd.DataFrame({'col1':[row[0]], 'label1':[0], 'label2':[1]})),ignore_index=True)
        df = pd.concat((df, pd.DataFrame({'col1':[row[0]], 'label1':[1], 'label2':[0]})), ignore_index=True)
        df.drop(index, inplace=True)

结果:

  col1  label1  label2
1    b       1       0
2    c       0       0
3    a       0       1
4    a       1       0

然后,您可以对col1

上的值进行排序

答案 2 :(得分:1)

这是一种思考问题的直观方式。首先,仅筛选标签均等于1的行。通过将每列替换为零来生成两个新数据帧。每个列。

然后连接原始数据帧,两行不等于创建的两个新数据帧。

mask_ones = (df['label1'] == 1) & (df['label2'] == 1)
df_ones = df[mask_ones]
df_not_ones = df[~mask_ones]
df_final = pd.concat([df_not_ones, 
                      df_ones.replace({'label2':{1:0}}),
                      df_ones.replace({'label1':{1:0}})]).sort_values('col1')

答案 3 :(得分:1)

分为2个df - 唯一且重复。 对于重复项,使用col1 + label1列并使用col1 + label2连接并使用0填充nan。 Concat是唯一的并且将df复制成一个:

df = pd.DataFrame([['a', 1, 1],
                   ['b', 1, 0],
                   ['c', 0, 0]], columns=['col1', 'label1', 'label2'])

mask = (df['label1'] == 1) & (df['label2'] == 1)
df_dup, df_uq = df[mask], df[~mask]
df_dup = pd.concat([df_dup[['col1', x]] for x in df_dup.columns if x != 'col1']).fillna(0)
df = pd.concat([df_dup, df_uq], ignore_index=True)
print(df)

  col1  label1  label2
0    a     1.0     0.0
1    a     0.0     1.0
2    b     1.0     0.0
3    c     0.0     0.0

答案 4 :(得分:0)

类似的东西:

df = pd.DataFrame([['a', 1, 1],
                   ['b', 1, 0],
                   ['c', 0, 0]] , columns=['col1', 'label1', 'label2'])
df2 = pd.DataFrame()
df2["col1"] = df["col1"]
df2["label2"] = df["label2"]
df.drop(labels="label2", axis=1, inplace=True)
result = df.append(df2, ignore_index=True)
result.fillna(value=0, inplace=True)
result.sort_values(by="col1")

结果:

  col1   label1   label2
0    a 1.000000 0.000000
3    a 0.000000 1.000000
1    b 1.000000 0.000000
4    b 0.000000 0.000000
2    c 0.000000 0.000000
5    c 0.000000 0.000000

最后,您可以删除重复项

result.drop_duplicates()
相关问题