web-dev-qa-db-ja.com

Python:Pandas文字列の長さに基づいて文字列データをフィルタリングする

文字列の長さが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)]
42
notilas
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
72
unutbu

他の列の特定の条件とその値に基づいて行をフィルタリングするより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")が文字列に存在するかどうかを確認し、最後に最初の列の整数値を確認します。

12
Mahdi Ghelichi

行に数値がある場合、それらは浮動小数点数として変換されます。

Cvsからインポートした後、すべての行を文字列に変換します。パフォーマンスを向上させるために、そのラムダを複数のスレッドに分割します。

1
przemo_li