gấu trúc ghi đè các giá trị trong nhiều cột cùng một lúc dựa trên điều kiện của các giá trị trong một cột


11

Tôi có DataFrame như vậy:

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']})

Tôi muốn lấy độ dài của danh sách sau khi tách trên ":" trong col1, sau đó tôi muốn ghi đè lên các giá trị nếu độ dài> 2 HOẶC không ghi đè lên các giá trị nếu độ dài <= 2.

Lý tưởng nhất, trong một dòng càng nhanh càng tốt.

Hiện tại, tôi đã thử nhưng nó trả về ValueError.

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

EDIT: điều kiện trên col1. EDIT2: cảm ơn bạn vì tất cả các câu trả lời tuyệt vời và nhanh chóng được cung cấp. kinh ngạc! EDIT3: thời gian trên 10 ^ 6 hàng:

@ansev 3.2657s

@jezrael 0.8922s

@ anky_91 1.9511


Là điều kiện trên col2hay col1?
anishtain4

Tôi xin lỗi vì sai lầm. Đó là col1.
dkrynicki

Câu trả lời:


8

Sử dụng Series.str.count, thêm 1, so sánh theo Series.gtvà gán danh sách cho các cột được lọc trong danh sách:

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
Đây là câu trả lời tốt nhất vì nó không lưu trữ phân chia tạm thời, nhưng tại sao không sử dụng gt(1)thay vì thêm 1 và gt(2)?
anishtain4

@ anishtain4 - yop, đồng ý
jezrael

10

Bạn cần series.str.len()sau khi chia để xác định độ dài của danh sách, sau đó bạn có thể so sánh và sử dụng .loc[], gán danh sách bất cứ nơi nào phù hợp với điều kiện:

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

Một cách tiếp cận khác là Series.str.splitvới expand = TrueDataFrame.countvới 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.