Python:Pandas根据字符串长度过滤字符串数据


72

我喜欢过滤掉字符串长度不等于10的数据。

如果我尝试过滤掉列A或B的字符串长度不等于10的任何行,则尝试这样做。

df=pd.read_csv('filex.csv')
df.A=df.A.apply(lambda x: x if len(x)== 10 else np.nan)
df.B=df.B.apply(lambda x: x if len(x)== 10 else np.nan)
df=df.dropna(subset=['A','B'], how='any')

这工作缓慢,但正在工作。

但是,当A中的数据不是字符串而是数字(在read_csv读取输入文件时解释为数字)时,有时会产生错误。

  File "<stdin>", line 1, in <lambda>
TypeError: object of type 'float' has no len()

我相信应该有更高效,更优雅的代码来代替。


根据下面的答案和评论,我找到的最简单的解决方案是:

df=df[df.A.apply(lambda x: len(str(x))==10]
df=df[df.B.apply(lambda x: len(str(x))==10]

要么

df=df[(df.A.apply(lambda x: len(str(x))==10) & (df.B.apply(lambda x: len(str(x))==10)]

要么

df=df[(df.A.astype(str).str.len()==10) & (df.B.astype(str).str.len()==10)]

Answers:


112
import pandas as pd

df = pd.read_csv('filex.csv')
df['A'] = df['A'].astype('str')
df['B'] = df['B'].astype('str')
mask = (df['A'].str.len() == 10) & (df['B'].str.len() == 10)
df = df.loc[mask]
print(df)

应用于filex.csv:

A,B
123,abc
1234,abcd
1234567890,abcdefghij

上面的代码打印

            A           B
2  1234567890  abcdefghij

20

根据其他列的给定条件及其值过滤行的更Python化方法:

假设df为:

data={"names":["Alice","Zac","Anna","O"],"cars":["Civic","BMW","Mitsubishi","Benz"],
     "age":["1","4","2","0"]}

df=pd.DataFrame(data)
df:
  age        cars  names
0   1       Civic  Alice
1   4         BMW    Zac
2   2  Mitsubishi   Anna
3   0        Benz      O

然后:

df[
df['names'].apply(lambda x: len(x)>1) &
df['cars'].apply(lambda x: "i" in x) &
df['age'].apply(lambda x: int(x)<2)
  ]

我们将有 :

  age   cars  names
0   1  Civic  Alice

在上述条件下,我们首先查看字符串的长度,然后检查字符串中是否存在字母(“ i”),最后检查第一列中的整数值。


6

我个人发现这种方法是最简单的:

df['column_name'] = df[df['column_name'].str.len()!=10]

虽然乍一看似乎更方便,但比使用apply慢,尤其是在较大的数据集上。
Smittie

1

如果行中有数字,则它们将转换为浮点数。

从cvs导入后,将所有行转换为字符串。为了获得更好的性能,请将lambda拆分为多个线程。



0

从A和B列中滤除长度10以外的值,这里我将lambda表达式传递给map()函数。map()函数始终适用于系列对象。

 df = df[df['A'].map(lambda x: len(str(x)) == 10)]
 df = df[df['B'].map(lambda x: len(str(x)) == 10)]

1
如果您解释了所提供的代码如何回答问题,那么这将是一个更好的答案。
pppery
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.