509

pandas DataFrameがあり、特定の列の文字列の長さが2より大きい行を削除したいと思います。

私はこれを行うことができると期待しています(この回答ごとに):

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

しかし、私はただエラーを受け取ります:

KeyError: u'no item named False'

私は何が間違っているのですか?

(注:をdf.dropna()含む行を削除するために使用できることはわかっていますNaNが、条件式に基づいて行を削除する方法がわかりませんでした。)

4

6 に答える 6

1245

この質問の元のタイトル「条件式に基づいて pandas DataFrame から行を削除する方法」に直接答えるには (これは必ずしも OP の問題ではないことを理解していますが、他のユーザーがこの質問に出くわすのに役立つ可能性があります)、これを行う 1 つの方法は、ドロップ方法:

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

列「スコア」が 50 未満のすべての行を削除するには:

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

インプレースバージョン(コメントで指摘されているとおり)

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

複数の条件

(ブール索引付けを参照)

演算子は、 |for or&for and、および~fornotです。これらは、括弧を使用してグループ化する必要があります。

列「スコア」が 50 未満で 20 を超えるすべての行を削除するには

df = df.drop(df[(df.score < 50) & (df.score > 20)].index)
于 2014-12-08T14:26:11.697 に答える
248

これを行うlen(df['column name'])と、1 つの数値、つまり DataFrame 内の行数 (つまり、列自体の長さ) を取得するだけです。len列の各要素に適用する場合は、 を使用しますdf['column name'].map(len)。だから試してみてください

df[df['column name'].map(len) < 2]
于 2012-12-13T01:37:01.637 に答える
146

DataFrameをそれ自体のフィルタリングされたバージョンに割り当てることができます。

df = df[df.score > 50]

これはより高速ですdrop:

%%timeit
test = pd.DataFrame({'x': np.random.randn(int(1e6))})
test = test[test.x < 0]
# 54.5 ms ± 2.02 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
test = pd.DataFrame({'x': np.random.randn(int(1e6))})
test.drop(test[test.x > 0].index, inplace=True)
# 201 ms ± 17.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
test = pd.DataFrame({'x': np.random.randn(int(1e6))})
test = test.drop(test[test.x > 0].index)
# 194 ms ± 7.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
于 2016-10-18T14:01:04.270 に答える
5

列値の複雑な条件に基づいてデータ フレームの行を削除する場合、上記の方法でそれを記述するのは複雑になる可能性があります。常に機能する次のより簡単なソリューションがあります。「ヘッダー」を含む列を削除したいので、最初にその列をリストに取得するとします。

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

リストのすべての要素にいくつかの関数を適用し、それを panda シリーズに入れます。

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

私の場合、トークンの数を取得しようとしていました:

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

ここで、データ フレームに上記の系列を含む列を 1 つ追加します。

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
于 2019-02-02T02:32:11.867 に答える