web-dev-qa-db-ja.com

列の値の長さに基づいてpandas dataframeから行を削除する方法は?

以下では pandas.DataFframe

df = 
    alfa    beta   ceta
    a,b,c   c,d,e  g,e,h
    a,b     d,e,f  g,h,k
    j,k     c,k,l  f,k,n

アルファの列の値が2つ以上の要素を持つ行を削除する方法は?これは長さ関数を使用して行うことができますが、特定の答えはわかりません。

df = df[['alfa'].str.split(',').map(len) < 3]
11
everestial007

pandas.DataFrame.apply()を使用して、各行に対して順番にテストを実行できます

print(df[df['alfa'].apply(lambda x: len(x.split(',')) < 3)])

与える:

  alfa   beta   ceta
1  a,b  d,e,f  g,h,k
2  j,k  c,k,l  f,k,n
5
Stephen Rauch

これは@NickilMaveliの回答のnumpyバージョンです。

mask = np.core.defchararray.count(df.alfa.values.astype(str), ',') <= 1
pd.DataFrame(df.values[mask], df.index[mask], df.columns)

  alfa   beta   ceta
1  a,b  d,e,f  g,h,k
2  j,k  c,k,l  f,k,n

素朴なタイミング

enter image description here

3
piRSquared

これどう?

df = df[df['alpha'].str.split(',', expand=True)[2].isnull()]

expand=Trueを使用すると、リスト内のアイテムごとに1つの列を持つ新しいデータフレームが作成されます。リストに3つ以上のアイテムがある場合、3番目の列はnull以外の値になります。

このアプローチの1つの問題は、リストに3つ以上の項目がない場合、列[2]を選択するとKeyErrorが発生することです。これに基づいて、@ Stephen Rauchによって投稿されたソリューションを使用する方が安全です。

2
Craig

指定されたDFをサブセット化するには、少なくとも2つの方法があります。

1)カンマ区切りで分割し、結果のlistの長さを計算します。

df[df['alfa'].str.split(",").str.len().lt(3)]

2)カンマの数を数え、結果に1を加えて最後の文字を考慮します。

df[df['alfa'].str.count(",").add(1).lt(3)] 

どちらも生成します:

enter image description here

2
Nickil Maveli

以下は、覚えやすく、Pandasの「出血の心臓」であるDataFrameを採用する最も簡単なオプションです。

1)データフレームに長さの値を持つ新しい列を作成します。

df['length'] = df.alfa.str.len()

2)新しい列を使用してインデックスを作成します。

df = df[df.length < 3]

次に、上記のタイミングとの比較。データは非常に小さいため、この場合はあまり関係がなく、通常、何かを行う方法を覚えてワークフローを中断する必要がないことよりも重要ではありません。

ステップ1:

%timeit df['length'] = df.alfa.str.len()

ループあたり359 µs±6.83 µs(7回の実行の平均±標準偏差、それぞれ1000ループ)

ステップ2:

df = df[df.length < 3]

ループあたり627 µs±76.9 µs(7回の実行の平均±標準偏差、それぞれ1000ループ)

良いニュースは、サイズが大きくなると、時間は直線的に伸びないことです。たとえば、30,000行のデータで同じ操作を行うと、約3msかかります(10,000xデータ、3倍の速度向上)。 Pandas DataFrameはトレインのようなものであり、それを実行するためにエネルギーを消費します(そのため、絶対的な比較では小さなものにはあまり適していませんが、客観的にはそれほど重要ではありません...小さなデータの場合と同様にとにかく速い)。

1
mikkokotila