98

我喜欢过滤掉字符串长度不等于 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)]
4

7 回答 7

162
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
于 2013-11-12T20:38:41.827 回答
30

根据其他列的给定条件及其值过滤出行的更 Pythonic 方式:

假设 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”),最后检查第一列中整数的值。

于 2017-07-13T04:02:20.240 回答
8

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

df['column_name'] = df[df['column_name'].str.len()!=10]
于 2020-05-05T16:36:38.983 回答
1

如果您在行中有数字,那么它们将转换为浮点数。

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

于 2013-11-12T18:54:05.210 回答
0

你可以使用df.apply(len). 它会给你结果

于 2019-02-27T21:08:49.337 回答
0

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

 df = df[df['A'].map(lambda x: len(str(x)) == 10)]
 df = df[df['B'].map(lambda x: len(str(x)) == 10)]
于 2020-06-16T13:18:26.583 回答
0

您可以使用 applymap 一次过滤您想要的所有列,然后使用 .all ()方法仅过滤两列都为 True 的行。

#The *mask* variable is a dataframe of booleans, giving you True or False for the selected condition
mask = df[['A','B']].applymap(lambda x: len(str(x)) == 10)

#Here you can just use the mask to filter your rows, using the method *.all()* to filter only rows that are all True, but you could also use the *.any()* method for other needs
df = df[mask.all(axis=1)]
于 2021-01-25T18:05:58.670 回答