パンダは、1つの列の値の条件に基づいて、一度に複数の列の値を上書きします


11

私はそのようなDataFrameを持っています:

df = pd.DataFrame(data={
    'col0': [11, 22,1, 5]
    'col1': ['aa:a:aaa', 'a:a', 'a', 'a:aa:a:aaa'],
    'col2': ["foo", "foo", "foobar", "bar"],
    'col3': [True, False, True, False],
    'col4': ['elo', 'foo', 'bar', 'dupa']})

col1の ":"で分割した後、リストの長さを取得したい場合、長さ> 2の場合は値を上書きするか、長さ<= 2の場合は値を上書きしないようにします。

理想的には、1行でできるだけ速く。

現在、私は試みますが、それはValueErrorを返します。

df[['col1', 'col2', 'col3']] = df.loc[df['col1'].str.split(":").apply(len) > 2], ("", "", False), df[['col1', 'col2', 'col3']])

編集:col1の条件。EDIT2:すべての素晴らしくて迅速な回答に感謝します。すごい!EDIT3:10 ^ 6行のタイミング:

@ansev 3.2657s

@jezrael 0.8922s

@ anky_91 1.9511s


上の条件ですcol2col1
anishtain4

私は間違いをお詫びします。col1です。
dkrynicki

回答:


8

リストのフィルターされた列にリストを使用Series.str.count、追加1、比較Series.gt、割り当て:

df.loc[df['col1'].str.count(":").add(1).gt(2), ['col1','col2','col3']] = ["", "", False]
print (df)
   col0 col1    col2   col3  col4
0    11               False   elo
1    22  a:a     foo  False   foo
2     1    a  foobar   True   bar
3     5               False  dupa

2
これは一時的な分割を保存しないので最良の答えですが、gt(1)1とgt(2)?を追加する代わりに使用しないのはなぜですか?
anishtain4

@ anishtain4-はい、同意します
jezrael

10

series.str.len()分割後、リストの長さを決定する必要があります。次に.loc[]、条件を一致させる場合は、リストを比較して使用し、リストを割り当てることができます。

df.loc[df['col1'].str.split(":").str.len()>2,['col1','col2','col3']]=["", "", False]
print(df)

   col0 col1    col2   col3  col4
0    11               False   elo
1    22  a:a     foo  False   foo
2     1    a  foobar   True   bar
3     5               False  dupa

5

別のアプローチはSeries.str.split、with expand = TrueおよびDataFrame.countwith axis=1です。

df.loc[df['col1'].str.split(":",expand = True).count(axis=1).gt(2),['col1','col2','col3']]=["", "", False]
print(df)
   col0 col1    col2   col3  col4
0    11               False   elo
1    22  a:a     foo  False   foo
2     1    a  foobar   True   bar
3     5               False  dupa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.