อัปเดตค่าแถวที่ตรงตามเงื่อนไขในแพนด้า


96

สมมติว่าฉันมี dataframe ต่อไปนี้:

ตาราง

เป็นวิธีที่มีประสิทธิภาพมากที่สุดในการปรับปรุงค่าของคอลัมน์อะไรสำเร็จและanother_featที่สตรีมเป็นจำนวน2 ?

นี่มัน?

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

UPDATE: จะทำอย่างไรถ้าฉันมีมากกว่า 100 คอลัมน์? ฉันไม่ต้องการตั้งชื่อคอลัมน์ที่ต้องการอัปเดตอย่างชัดเจน ฉันต้องการหารค่าของแต่ละคอลัมน์ด้วย 2 (ยกเว้นคอลัมน์สตรีม)

เพื่อให้ชัดเจนว่าเป้าหมายของฉันคืออะไร:

หารค่าทั้งหมดด้วย 2 แถวทั้งหมดที่มีสตรีม 2 แต่ไม่เปลี่ยนคอลัมน์สตรีม

คำตอบ:


199

ฉันคิดว่าคุณสามารถใช้ได้locถ้าคุณต้องการอัปเดตสองคอลัมน์ให้เป็นค่าเดียวกัน:

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

หากคุณต้องการอัปเดตแยกต่างหากให้ใช้ตัวเลือกหนึ่ง:

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

อีกทางเลือกหนึ่งคือการใช้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

แก้ไข: หากคุณต้องการแบ่งคอลัมน์ทั้งหมดโดยไม่มีstreamเงื่อนไขTrueให้ใช้:

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

ฉันอัปเดตคำถามของฉันมีคอลัมน์มากกว่า 100 คอลัมน์ฉันจะทำอย่างไร
Stanko

1
@Stanko - ฉันคิดว่ามันเป็นอีกคำถามหนึ่ง - คุณต้องเลือก100คอลัมน์นี้บ้าง เช่นถ้าจำเป็นต้อง100คอลัมน์แรกที่ใช้แล้วก็ผ่านไปdf.columns[:100] loc
jezrael

ฉันไม่ต้องการ 100 คอลัมน์แรกฉันแค่ต้องการหารค่าทั้งหมดของคอลัมน์ (ยกเว้นคอลัมน์สตรีม) ด้วย 2 โดยที่สตรีมคือ fe 2
Stanko

ดังนั้นความแตกต่างระหว่าง loc และ np โดยที่ loc เปลี่ยนแถวที่ตอบสนองเงื่อนไขเท่านั้น แต่ np มีคำสั่ง if และ else ที่ไหนดังนั้นมันจะเปลี่ยนแถวทั้งหมด
Ambleu

1
@ แอมเบลอ - เป๊ะ.
jezrael

3

คุณสามารถทำเช่นเดียวกันกับ.ixสิ่งนี้:

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

แก้ไข

หลังจากข้อมูลเพิ่มเติมข้อมูลต่อไปนี้จะส่งคืนคอลัมน์ทั้งหมด - เมื่อตรงตามเงื่อนไข - โดยมีค่าครึ่งหนึ่ง:

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

ฉันหวังว่านี่จะช่วยได้!


สิ่งนี้ทำได้ถ้าฉันมีคอลัมน์ไม่มากฉันควรบอกว่าฉันมีมากกว่า 100 คอลัมน์
Stanko

ฉันทดสอบการแก้ไขครั้งล่าสุดของคุณโดยcondition = (df.a == -1.001287)คาดหวังว่าค่าจะถูกแบ่งออกจากแถวที่a == -1.001287แต่ฉันกลับได้ดาต้าเฟรมว่างเปล่า
Stanko

df.iloc[1,0]ใช่นี้เป็นเพราะนี้เป็นเพียงการแสดงผลที่ไม่ได้มูลค่าที่แท้จริงได้รับมูลค่าที่แท้จริงเช่นนี้ หรือควรตั้งค่าด้วยตัวเองแล้วลองอีกครั้ง:df.iloc[1,0] = 1.2345; condition = df.a == 1.2345
Thanos

ฉันไม่ได้ติดตามทำไมถึงใช้condition = (df.a == -1.001287)งานไม่ได้?
Stanko

8
ixเลิกใช้งานแล้ว
dbliss
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.