Cập nhật giá trị hàng nơi đáp ứng điều kiện nhất định trong gấu trúc


96

Giả sử tôi có khung dữ liệu sau:

bàn

Cách hiệu quả nhất để cập nhật các giá trị của cột featanother_feat trong đó luồng là số 2 là gì?

Đây có phải là nó?

for index, row in df.iterrows():
    if df1.loc[index,'stream'] == 2:
       # do something

CẬP NHẬT: Phải làm gì nếu tôi có hơn 100 cột? Tôi không muốn đặt tên rõ ràng cho các cột mà tôi muốn cập nhật. Tôi muốn chia giá trị của mỗi cột cho 2 (ngoại trừ cột luồng).

Vì vậy, để rõ ràng mục tiêu của tôi là:

Chia tất cả các giá trị cho 2 trong số tất cả các hàng có luồng 2, nhưng không thay đổi cột luồng

Câu trả lời:


199

Tôi nghĩ bạn có thể sử dụng locnếu bạn cần cập nhật hai cột thành cùng một giá trị:

df1.loc[df1['stream'] == 2, ['feat','another_feat']] = 'aaaa'
print df1
   stream        feat another_feat
a       1  some_value   some_value
b       2        aaaa         aaaa
c       2        aaaa         aaaa
d       3  some_value   some_value

Nếu bạn cần cập nhật riêng, một tùy chọn là sử dụng:

df1.loc[df1['stream'] == 2, 'feat'] = 10
print df1
   stream        feat another_feat
a       1  some_value   some_value
b       2          10   some_value
c       2          10   some_value
d       3  some_value   some_value

Một lựa chọn phổ biến khác là sử dụng numpy.where:

df1['feat'] = np.where(df1['stream'] == 2, 10,20)
print df1
   stream  feat another_feat
a       1    20   some_value
b       2    10   some_value
c       2    10   some_value
d       3    20   some_value

CHỈNH SỬA: Nếu bạn cần chia tất cả các cột mà không streamcó điều kiện True, hãy sử dụng:

print df1
   stream  feat  another_feat
a       1     4             5
b       2     4             5
c       2     2             9
d       3     1             7

#filter columns all without stream
cols = [col for col in df1.columns if col != 'stream']
print cols
['feat', 'another_feat']

df1.loc[df1['stream'] == 2, cols ] = df1 / 2
print df1
   stream  feat  another_feat
a       1   4.0           5.0
b       2   2.0           2.5
c       2   1.0           4.5
d       3   1.0           7.0

Tôi đã cập nhật câu hỏi của mình, tôi có hơn 100 cột, làm thế nào tôi có thể làm điều này?
Stanko

1
@Stanko - Tôi nghĩ đó là một câu hỏi khác - bạn cần chọn 100cột này theo cách nào đó. Ví dụ: nếu cần 100các cột đầu tiên, hãy sử dụng df.columns[:100]và sau đó nó chuyển đến loc.
jezrael

Tôi không nhất thiết muốn 100 cột đầu tiên, tôi chỉ muốn chia tất cả giá trị của các cột (ngoại trừ cột luồng) cho 2 trong đó luồng là fe 2
Stanko

vì vậy sự khác biệt giữa loc và np.where là loc thay đổi các hàng chỉ thỏa mãn điều kiện nhưng np.where có câu lệnh if và else do đó nó sẽ thay đổi tất cả các hàng?
Ambleu

1
@Ambleu - chính xác.
jezrael

3

Bạn có thể làm điều tương tự với .ix, như sau:

In [1]: df = pd.DataFrame(np.random.randn(5,4), columns=list('abcd'))

In [2]: df
Out[2]: 
          a         b         c         d
0 -0.323772  0.839542  0.173414 -1.341793
1 -1.001287  0.676910  0.465536  0.229544
2  0.963484 -0.905302 -0.435821  1.934512
3  0.266113 -0.034305 -0.110272 -0.720599
4 -0.522134 -0.913792  1.862832  0.314315

In [3]: df.ix[df.a>0, ['b','c']] = 0

In [4]: df
Out[4]: 
          a         b         c         d
0 -0.323772  0.839542  0.173414 -1.341793
1 -1.001287  0.676910  0.465536  0.229544
2  0.963484  0.000000  0.000000  1.934512
3  0.266113  0.000000  0.000000 -0.720599
4 -0.522134 -0.913792  1.862832  0.314315

BIÊN TẬP

Sau thông tin bổ sung, phần sau sẽ trả về tất cả các cột - nơi đáp ứng một số điều kiện - với các giá trị giảm đi một nửa:

>> condition = df.a > 0
>> df[condition][[i for i in df.columns.values if i not in ['a']]].apply(lambda x: x/2)

Tôi hi vọng cái này giúp được!


Điều này có thể làm được nếu tôi không có nhiều cột, tôi nên nói rằng tôi có hơn 100 cột.
Stanko

Tôi đã thử nghiệm lần chỉnh sửa cuối cùng của bạn với condition = (df.a == -1.001287)hy vọng các giá trị sẽ được chia cho hàng mà a == -1.001287tôi nhận được một khung dữ liệu trống.
Stanko

Vâng, đây là bởi vì đây chỉ là màn hình hiển thị, không phải là giá trị thực, có giá trị thực như thế này: df.iloc[1,0]. Hoặc tốt hơn là bạn hãy tự đặt giá trị và sau đó thử lại:df.iloc[1,0] = 1.2345; condition = df.a == 1.2345
Thanos

Tôi không theo dõi, tại sao chính xác là condition = (df.a == -1.001287)không hoạt động?
Stanko

8
ixhiện không được dùng nữa.
dbliss
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.