如何基于条件表达式从pandas DataFrame中删除行

时间:2012-12-13 01:28:25

标签: python pandas

我有一个pandas DataFrame,我想从中删除特定列中字符串长度大于2的行。我知道我可以使用df.dropna()来删除包含任何{的行{1}},但我没有看到如何根据条件表达式删除行。

this question的答案似乎与我想要的非常接近 - 似乎我应该能够做到这样的事情:

NaN

但我得到错误:

df[(len(df['column name']) < 2)]

谁能告诉我我做错了什么?

7 个答案:

答案 0 :(得分:561)

直接回答这个问题的标题(我理解的不一定是OP的问题,但可以帮助其他用户遇到这个问题)一种方法是使用{{3}方法:

df = df.drop(some labels)

df = df.drop(df[<some boolean condition>].index)

示例

删除列&#39;得分&#39;的所有行是&lt; 50:

df = df.drop(df[df.score < 50].index)

到位版(如评论中所指出)

df.drop(df[df.score < 50].index, inplace=True)

多个条件

(见drop

  

运算符为| or&and~not。这些必须是   使用括号分组。

删除列&#39;得分&#39;的所有行是&lt; 50和&gt; 20

df = df.drop(df[(df.score < 50) & (df.score > 20)].index)

答案 1 :(得分:118)

执行len(df['column name'])时,您只得到一个数字,即DataFrame中的行数(即列本身的长度)。如果您要将len应用于列中的每个元素,请使用df['column name'].map(len)。所以试试

df[df['column name'].map(len) < 2]

答案 2 :(得分:74)

您可以将RemoteWebDriver driver = new AndroidDriver<MobileElement>//this gets NPE below //new RemoteWebDriver //this works!! (new URL("http://127.0.0.1:4723/wd/hub"), capabilities); Thread.sleep(15000); new WebDriverWait(driver, 30).until( ExpectedConditions.presenceOfElementLocated( By.xpath("//*[contains(@text, 'Tan')]"))); 分配给自身的过滤版本:

DataFrame

这比df = df[df.score > 50]

更快
drop

答案 3 :(得分:4)

在熊猫中,您可以对边界进行str.len并使用布尔结果对其进行过滤。

df[df['column name'].str.len().lt(2)]

答案 4 :(得分:2)

如果要基于某些复杂的条件在列值上删除数据帧的行,则以上述方式编写代码可能会很复杂。我有以下始终有效的简单解决方案。让我们假设您要删除带有“ header”的列,以便首先在列表中获得该列。

text_data = df ['name']。tolist()

现在在列表的每个元素上应用一些功能,并将其放入熊猫系列:

text_length = pd.Series([text_data中t的func(t)])

就我而言,我只是想获取令牌数量:

text_length = pd.Series([text_data中t的len(t.split())])

现在在数据框中添加一个具有上述系列的额外列:

df = df.assign(text_length = text_length .values)

现在我们可以将条件应用于新列,例如:

df = df [df.text_length> 10]

具有此功能的文本的低/高通滤波器如下:

def pass_filter(df, label, length, pass_type):

    text_data = df[label].tolist()

    text_length = pd.Series([len(t.split()) for t in text_data])

    df = df.assign(text_length = text_length .values)

    if pass_type == 'high':
        df = df[df.text_length  >  length]

    if pass_type == 'low':
        df = df[df.text_length  <  length]

    df = df.drop(columns=['text_length'])

    return df

答案 5 :(得分:2)

我将扩展@User的通用解决方案,以提供免费的drop替代方案。这是针对根据问题标题(不是OP的问题)定向到此处的人

假设您要删除所有带有负值的行。一种班轮解决方案是:-

df = df[(df > 0).all(axis=1)]

分步说明:-

让我们生成5x5随机正态分布数据帧

np.random.seed(0)
df = pd.DataFrame(np.random.randn(5,5), columns=list('ABCDE'))
      A         B         C         D         E
0  1.764052  0.400157  0.978738  2.240893  1.867558
1 -0.977278  0.950088 -0.151357 -0.103219  0.410599
2  0.144044  1.454274  0.761038  0.121675  0.443863
3  0.333674  1.494079 -0.205158  0.313068 -0.854096
4 -2.552990  0.653619  0.864436 -0.742165  2.269755

让条件为删除底片。满足以下条件的布尔df:-

df > 0
      A     B      C      D      E
0   True  True   True   True   True
1  False  True  False  False   True
2   True  True   True   True   True
3   True  True  False   True  False
4  False  True   True  False   True

所有满足条件的行的布尔系列请注意,如果该行中的任何元素失败,则该行将被标记为false

(df > 0).all(axis=1)
0     True
1    False
2     True
3    False
4    False
dtype: bool

最后根据条件从数据框中过滤出行

df[(df > 0).all(axis=1)]
      A         B         C         D         E
0  1.764052  0.400157  0.978738  2.240893  1.867558
2  0.144044  1.454274  0.761038  0.121675  0.443863

您可以将其分配回df,以便实际上完成上述的删除 vs 过滤器
df = df[(df > 0).all(axis=1)]

可以很容易地扩展它以过滤出包含NaN的行(非数字条目):-
df = df[(~df.isnull()).all(axis=1)]

在以下情况下也可以简化此操作:删除E列为负的所有行

df = df[(df.E>0)]

我想以一些分析统计数据结尾,说明为什么@User的drop解决方案比基于原始列的过滤要慢:-

%timeit df_new = df[(df.E>0)]
345 µs ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit dft.drop(dft[dft.E < 0].index, inplace=True)
890 µs ± 94.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

一列基本上是Series,即NumPy数组,可以对其进行索引而无需花费任何费用。对于对基础内存组织如何发挥执行速度感兴趣的人们,这里是一个不错的Link on Speeding up Pandas

答案 6 :(得分:-1)

要从熊猫数据框中删除一行或n行,可以使用以下命令

DataFrame.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')

参考:https://www.toogit.com/tlc/article/how-to-delete-rows-from-pandas-dataframe