Porównaj dwie kolumny używając pand

Używanie tego jako punktu wyjścia:

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

Out[8]: 
  one  two three
0   10  1.2   4.2
1   15  70   0.03
2    8   5     0

Chcę użyć czegoś w rodzaju if Oświadczenia wewnątrz pand.

if df['one'] >= df['two'] and df['one'] <= df['three']:
    df['que'] = df['one']

Zasadniczo, sprawdź każdy wiersz za pomocą instrukcji if, Utwórz nową kolumnę.

Dokumenty mówią, aby użyć .all, ale nie ma przykładu...

Author: Alex Riley, 2014-12-15

6 answers

Przydałoby się np.gdzie . Jeśli cond jest tablicą boolowską, a A i {[11] } są tablicami, to

C = np.where(cond, A, B)

Definiuje C jako równe A gdzie cond jest prawdziwe, a B gdzie cond jest fałszywe.

import numpy as np
import pandas as pd

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

df['que'] = np.where((df['one'] >= df['two']) & (df['one'] <= df['three'])
                     , df['one'], np.nan)

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03  NaN
2   8    5     0  NaN

Jeśli masz więcej niż jeden warunek, możesz użyć np.zamiast tego wybierz . Na przykład, jeśli chcesz {[16] } równa df['two'] kiedy df['one'] < df['two'], to

conditions = [
    (df['one'] >= df['two']) & (df['one'] <= df['three']), 
    df['one'] < df['two']]

choices = [df['one'], df['two']]

df['que'] = np.select(conditions, choices, default=np.nan)

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03   70
2   8    5     0  NaN

Jeśli możemy założyć, że df['one'] >= df['two'] gdy df['one'] < df['two'] jest False, wtedy warunki i wybory mogą być uproszczone do

conditions = [
    df['one'] < df['two'],
    df['one'] <= df['three']]

choices = [df['two'], df['one']]

(założenie może nie być prawdziwe, jeśli df['one'] lub df['two'] zawierają Nan.)


Zauważ, że

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

Definiuje ramkę danych z wartościami łańcuchowymi. Ponieważ wyglądają numerycznie, może być lepiej konwertować te ciągi na pływaki: {]}

df2 = df.astype(float)

Zmienia to jednak wyniki, ponieważ ciągi znaków porównują znak po znaku, podczas gdy Floaty są porównywane numerycznie.

In [61]: '10' <= '4.2'
Out[61]: True

In [62]: 10 <= 4.2
Out[62]: False
 49
Author: unutbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-15 11:44:27

Możesz użyć .equals dla kolumn lub całych ramek danych.

df['col1'].equals(df['col2'])

Jeśli są równe, to polecenie zwróci True, else False.

 22
Author: ccook5760,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-25 22:09:21

Możesz użyć apply() i zrobić coś takiego

df['que'] = df.apply(lambda x : x['one'] if x['one'] >= x['two'] and x['one'] <= x['three'] else "", axis=1)

Lub jeśli wolisz nie używać lambda

def que(x):
    if x['one'] >= x['two'] and x['one'] <= x['three']:
        return x['one']
    else:
        ''
df['que'] = df.apply(que, axis=1)
 18
Author: Bob Haffner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-14 23:21:20

Jednym ze sposobów jest użycie serii logicznej do indeksowania Kolumny df['one']. Daje to nową kolumnę, w której wpisy True mają taką samą wartość jak ten sam wiersz co df['one'], a wartości False to NaN.

Seria logiczna jest po prostu podana przez twoje if oświadczenie (chociaż konieczne jest użycie & zamiast and):

>>> df['que'] = df['one'][(df['one'] >= df['two']) & (df['one'] <= df['three'])]
>>> df
    one two three   que
0   10  1.2 4.2      10
1   15  70  0.03    NaN
2   8   5   0       NaN

Jeśli chcesz, aby wartości NaN zostały zastąpione innymi wartościami, możesz użyć metody fillna w nowej kolumnie que. Użyłem 0 zamiast pusty łańcuch tutaj:

>>> df['que'] = df['que'].fillna(0)
>>> df
    one two three   que
0   10  1.2   4.2    10
1   15   70  0.03     0
2    8    5     0     0
 7
Author: Alex Riley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-14 22:54:11

Zawiń każdy warunek w nawiasach, a następnie użyj operatora &, aby połączyć warunki:

df.loc[(df['one'] >= df['two']) & (df['one'] <= df['three']), 'que'] = df['one']

Możesz wypełnić niepasujące wiersze, po prostu używając ~ (operatora "nie"), aby odwrócić dopasowanie:

df.loc[~ ((df['one'] >= df['two']) & (df['one'] <= df['three'])), 'que'] = ''

Musisz używać & i ~ zamiast and i not, ponieważ operatory & i ~ działają element po elemencie.

Wynik końcowy:

df
Out[8]: 
  one  two three que
0  10  1.2   4.2  10
1  15   70  0.03    
2   8    5     0  
 4
Author: Marius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-14 22:47:01

Myślę, że najbliżej intuicji OP jest twierdzenie inline if:

df['que'] = (df['one'] if ((df['one'] >= df['two']) and (df['one'] <= df['three'])) 
 0
Author: Nic Scozzaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-12 19:28:10