Доступ к следующей, предыдущей или текущей строке в назначении панд .loc [] - PullRequest
0 голосов
/ 09 декабря 2018

В разделе if-then документации pandas поваренная книга мы можем присвоить значения в одном столбце на основе условия, выполняемого для отдельного столбца, с помощью loc[].

 df = pd.DataFrame({'AAA' : [4,5,6,7], 
'BBB' : [10,20,30,40],
'CCC' : [100,50,-30,-50]})
#    AAA  BBB  CCC
# 0    4   10  100
# 1    5   20   50
# 2    6   30  -30
# 3    7   40  -50

df.loc[df.AAA >= 5,'BBB'] = -1
#    AAA  BBB  CCC
# 0    4   10  100
# 1    5   -1   50
# 2    6   -1  -30
# 3    7   -1  -50

Но что, если я хочу написать условие, которое включает в себя предыдущую или последующую строку, используя .loc[]?Например, я хочу назначить df.BBB=5 везде, где разница между df.CCC текущей строки и df.CCC следующей строки больше или равна 50. Затем я хотел бы создать условие, которое даетмне следующий фрейм данных:

#    AAA  BBB  CCC
# 0    4    5  100 <-| 100 - 50 = 50, assign df.BBB = 5
# 1    5    5   50 <-| 50 -(-30)= 80, assign df.BBB = 5 
# 2    6   -1  -30 <-| 30 -(-50)= 20, don't assign df.BBB = 5
# 3    7   -1  -50 <-| (-50) -0 =-50, don't assign df.BBB = 5

Как я могу получить этот результат?

Редактировать Ответ, который я надеюсь найти, что-то вроде

mask = df['CCC'].current - df['CCC'].next >= 50
df.loc[mask, 'BBB'] = 5

, потому что меня интересует общая проблема, связанная с тем, как я могу получить доступ к значениям выше или ниже текущей строки, рассматриваемой в кадре данных (необязательно для решения этого одного игрушечного примера.)

diff() будет работать на примере, который я только что описал, но в каком другом случае, скажем, мы хотим сравнить два элемента, а не вычесть их?

Что если я возьму предыдущий фрейм данных и хочу найти всестроки, в которых текущая запись столбца не соответствует следующей в df.BBB, а затем присваивается df.CCC на основе этих сравнений?

if df.BBB.current == df.CCC.next:
    df.CCC = 1

#    AAA  BBB  CCC     
# 0    4    5    1 <-|  5 ==  5, assign df.CCC = 1
# 1    5    5   50 <-|  5 != -1, do nothing
# 2    6   -1    1 <-| -1 == -1, assign df.CCC = 1
# 3    7   -1  -50 <-| -1 !=  0, do nothing

Есть ли способ сделать это с пандами, используя .loc[]?

1 Ответ

0 голосов
/ 09 декабря 2018

Учитывая

>>> df
   AAA  BBB  CCC
0    4   10  100
1    5   20   50
2    6   30  -30
3    7   40  -50

, вы можете сначала вычислить логическую маску с помощью

>>> mask = df['CCC'].diff(-1) >= 50
>>> mask
0     True
1     True
2    False
3    False
Name: CCC, dtype: bool

, а затем выполнить

>>> df.loc[mask, 'BBB'] = 5
>>> 
>>> df
   AAA  BBB  CCC
0    4    5  100
1    5    5   50
2    6   30  -30
3    7   40  -50

В целом, вы можетевычислите смещение

>>> df['CCC_next'] = df['CCC'].shift(-1) # or df['CCC'].shift(-1).fillna(0)
>>> df
   AAA  BBB  CCC  CCC_next
0    4    5  100      50.0
1    5    5   50     -30.0
2    6   30  -30     -50.0
3    7   40  -50       NaN

... и затем делайте все, что хотите, например:

>>> df['CCC'].sub(df['CCC_next'], fill_value=0)
0    50.0
1    80.0
2    20.0
3   -50.0
dtype: float64
>>> mask = df['CCC'].sub(df['CCC_next'], fill_value=0) >= 50
>>> mask
0     True
1     True
2    False
3    False
dtype: bool

, хотя для конкретной проблемы в вашем вопросе достаточно подхода diff.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...