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


96

Скажімо, у мене є такий фрейм даних:

таблиця

Який найефективніший спосіб оновити значення стовпців feat та another_feat, де потік номер 2 ?

Це це?

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

ОНОВЛЕННЯ: Що робити, якщо у мене більше 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 стовпців, як я міг це зробити?
Станко

1
@Stanko - Я думаю, це інше питання - вам потрібно 100якось вибрати ці стовпці. наприклад, якщо потрібні 100перші стовпці, використовуйте, df.columns[:100]а потім переходьте до loc.
jezrael

Я не обов'язково хочу перші 100 стовпців, я просто хочу розділити всі значення стовпців (крім стовпця потоку) на 2, де потік fe 2
Станко

отже, різниця між loc і np.where полягає в тому, що loc змінює рядки, які задовольняють лише умові, але np.where має оператор if та else, отже, він змінить всі рядки?
Амбле

1
@Ambleu - точно.
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 стовпців.
Станко

Я перевірив ваше останнє редагування, condition = (df.a == -1.001287)очікуючи, що значення будуть розділені на рядок, де, a == -1.001287але я повернув порожній кадр даних.
Станко

Так, це тому , що це тільки дисплей, а не реальна значення, отримати реальне значення , як це: df.iloc[1,0]. Або ще краще встановіть значення самостійно, а потім спробуйте ще раз:df.iloc[1,0] = 1.2345; condition = df.a == 1.2345
Танос

Я не стежу, чому саме condition = (df.a == -1.001287)не працює?
Станко

8
ixзараз застаріла.
dbliss
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.