【问题标题】:DataFrame drop rows whose column has certain valuesDataFrame 删除其列具有特定值的行
【发布时间】:2016-10-04 21:38:52
【问题描述】:

对于我的问题,我找到了很多解释如何删除具有特定列值的行的条目;但是,我无法找到(我知道可能有一篇文章)一篇文章解决了如何在数据框中删除具有跨多个列(在本例中为 34 个)的特定列值的行。

  1. How to drop rows of Pandas DataFrame whose value in certain columns is NaN
  2. Drop Rows by Multiple Column Criteria in DataFrame
  3. Drop rows in pandas dataframe based on columns value

坏数据

zip        age    item1    item2    item3    item4    item5    item6    item7    item34

12345       10    1        0        1        1        0         0       1           0

23456       20   10       111       11       1        0         1       9           8

45678       60    1        0         1       1        0         1       0           1

我想保留所有值为 '1' 或 '0' 的行(删除 34 列中 col 值不是 '1' 或 '0' 的所有行)。这是我迄今为止尝试过的:

baddata = pd.DataFrame(data=dirtydata, columns=['zip','age','item1','item2'...'item34'])

gooddata=baddata.dropna() # 一些行有 NaN;删除具有 NaN 值的行

选项-1:

gooddata[gooddata[['item1','item2'...'item34']].isin([0,1])] #this 生成 zip 和 age NaN 的值;不知道为什么?

选项-2:

gooddata[gooddata[['item1','item2'...'item34']].map(len)

选项-3:

cols_of_interest=['item1','item2'...'item34'] gooddata[gooddata.drop(gooddata[cols_of_interest].map(len)

【问题讨论】:

  • 让我明确一点,您想删除所有item34 中的值不是01 的行吗?这是你想要的吗?就这样?
  • Joe R - 我只想为各种项目保留那些值为 '0' 或 '1' 的行,即删除所有那些值不是 '0' 或 '1' 的行cols item1, item2, item3, item4,...item34 中的值。
  • 预期结果:邮编 item1 item2 item3 item4 item5 item6 item7 item34 12345 10 1 0 1 1 0 0 1 0 45678 60 1 0 1 1 0 1 0 1
  • @Merlin 如何使用 row1 和 row3 中所述的良好数据获得预期结果。 row2 是一个示例,说明如何必须删除或不保留数据框中的值不是 1 或 0 的不同项目。希望我不会让它太混乱。
  • 认为我已经在下面回答了这个问题。

标签: python dataframe


【解决方案1】:

首先选择age之后的所有列

df[df.columns[2:]]

   item1  item2  item3  item4  item5  item6  item7  item34
0      1      0      1      1      0      0      1       0
1     10    111     11      1      0      1      9       8
2      1      0      1      1      0      1      0       1

检查它们的值是 0 还是 1

df[df.columns[2:]].isin((0, 1))

   item1  item2  item3 item4 item5 item6  item7 item34
0   True   True   True  True  True  True   True   True
1  False  False  False  True  True  True  False  False
2   True   True   True  True  True  True   True   True

检查行中的所有值是否为真

df[df.columns[2:]].isin((0, 1)).all(axis=1)

0    True
1    False
2    True
dtype: bool

只选择这些行

df[df[df.columns[2:]].isin((0, 1)).all(axis=1)]

     zip  age  item1  item2  item3  item4  item5  item6  item7  item34
0  12345   10      1      0      1      1      0      0      1       0
2  45678   60      1      0      1      1      0      1      0       1

编辑

更清楚一点,我们有

relevant_columns = df[df.columns[2:]]
values_as_ints = relevant_columns.convert_objects(convert_numeric=True)
values_valid = values_as_ints.isin((0, 1))
row_valid = values_valid.all(axis=1)
good_rows = df[row_valid]

【讨论】:

  • DataFrame 中的值是strings 还是ints?
  • 它们的类型为浮点、整数、对象。我应该澄清一下。
  • 你可以试试df[df[df.columns[2:]].astype(int).isin((0, 1)).all(axis=1)]
  • @karasinski 收到此错误消息:long() 以 10 为基数的无效文字:' '
  • 解决您的问题很困难,因为您在上面发布的示例数据中没有出现这些问题。我在上面编辑了我的答案,你能试试吗?
【解决方案2】:

试试这个:

 print df
 zip     age  item1  item2  item3  item4  item5  item6  item7  item34
12345   10      1      0      1      1      0      0      1       0
23456   20     10    111     11      1      0      1      9       8
45678   60      1      0      1      1      0      1      0       1

dfSlice = df[df.columns[2:]]
def mapZeroOne(x):
    if x == 0 or x == 1:   
       return x

dfNa = dfSlice.applymap(mapZeroOne)
print dfNa

      item1  item2  item3  item4  item5  item6  item7  item34
12345    1.0    0.0    1.0      1      0      0    1.0     0.0
23456    NaN    NaN    NaN      1      0      1    NaN     NaN
45678    1.0    0.0    1.0      1      0      1    0.0     1.0

dfAge =  df[['zip',"age"]] 
print  dfAge

zip     age
12345   10
23456   20
45678   60


df_new = pd.concat([dfAge, dfNa], axis=1)
 print df_new 

zip     age  item1  item2  item3  item4  item5  item6  item7  item34
12345   10    1.0    0.0    1.0      1      0      0    1.0     0.0
23456   20    NaN    NaN    NaN      1      0      1    NaN     NaN
45678   60    1.0    0.0    1.0      1      0      1    0.0     1.0

print df_new.dropna()

zip    age  item1  item2  item3  item4  item5  item6  item7  item34
12345   10    1.0    0.0    1.0      1      0      0    1.0     0.0
45678   60    1.0    0.0    1.0      1      0      1    0.0     1.0

您可能需要将 0 调整为“0”,将 1 调整为“1”。

【讨论】:

  • 为什么我只使用特定的 'item34' 进行按位运算?其他项目也可能具有无效的数据值,如第 1 行所示。试图了解按位运算的用法和只有item34的具体用法