панди перезаписують значення в декількох стовпцях одночасно, виходячи з умови значень в одному стовпці


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.

В ідеалі в один рядок якомога швидше.

В даний час я намагаюся, але він повертає ValueError.

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

EDIT: умова на col1. EDIT2: дякую за всі чудові та швидко надані відповіді. дивовижний! EDIT3: відмітка часу на 10 ^ 6 рядків:

@ansev 3.2657s

@jezrael 0.8922s

@ anky_91 1.9511с


Чи є стан на col2або col1?
anishtain4

Я прошу вибачення за помилку. Це col1.
dryrynicki

Відповіді:


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 - yop, згоден
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з expand = Trueі DataFrame.countз 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.