для цикла для сравнения строк в пандах - PullRequest
0 голосов
/ 24 ноября 2018

У меня есть следующий pandas dataframe

code      tank     prod_receipt      tank_prod
12345     1        MS                MS
23452     2        MS                No Data
23333     2        HS                HS
14567     3        MS                No Data
12343     2        MS                MS

Я хочу сгенерировать флаг, в котором проверяется, равен ли prod_receipt tank_prod Мой желаемый фрейм данных

code      tank     prod_receipt      tank_prod    Flag
12345     1        MS                MS           Equal
23452     2        MS                No Data      No Data
23333     2        HS                HS           Equal
14567     3        MS                No Data      No Data
12343     2        MS                HS           Not Equal

Как я могу сделать это в пандах?

Ответы [ 3 ]

0 голосов
/ 24 ноября 2018

Просто сделайте это:

flag_dict={
True: 'Equal',
False: 'Not Equal'
}

df['flag'] = df['prod_receipt']== df['tank_prod']
df['flag'] = df['flag'].apply(lambda row: flag_dict[row] )
0 голосов
/ 24 ноября 2018

Использование .apply ()

df["Flag"] = df.apply(lambda x: "Equal" if x["prod_receipt"] == x["tank_prod"] else ("Not Equal" if x["prod_receipt"] != x["tank_prod"] and  x["tank_prod"] != "No Data" else "No Data"), axis =1)

Вывод:

    code  tank prod_receipt tank_prod       Flag
0  12345     1           MS        MS      Equal
1  23452     2           MS   No Data    No Data
2  23333     2           HS        HS      Equal
3  14567     3           MS   No Data    No Data
4  12343     2           MS        HS  Not Equal
0 голосов
/ 24 ноября 2018

Не используйте циклы, потому что медленнее, лучше использовать numpy.select:

m1 = df['tank_prod'] == 'No Data'
m2 = df['prod_receipt'] == df['tank_prod']
df['new'] = np.select([m1, m2], ['No Data', 'Equal'],'Not Equal')
print (df)
    code  tank prod_receipt tank_prod        new
0  12345     1           MS        MS      Equal
1  23452     2           MS   No Data    No Data
2  23333     2           HS        HS      Equal
3  14567     3           MS   No Data    No Data
4  12343     2           MS        HS  Not Equal

Если нужно только одно условие, используйте numpy.where:

m2 = df['prod_receipt'] == df['tank_prod']
df['new'] = np.where(m2, 'Equal','Not Equal')
print (df)
    code  tank prod_receipt tank_prod        new
0  12345     1           MS        MS      Equal
1  23452     2           MS   No Data  Not Equal
2  23333     2           HS        HS      Equal
3  14567     3           MS   No Data  Not Equal
4  12343     2           MS        HS  Not Equal

Производительность :

Зависит от количества строк и количества совпадающих значений:

#4k rows
df = pd.concat([df] * 1000, ignore_index=True)

In [90]: %%timeit
    ...: m1 = df['tank_prod'] == 'No Data'
    ...: m2 = df['prod_receipt'] == df['tank_prod']
    ...: df['new'] = np.select([m1, m2], ['No Data', 'Equal'],'Not Equal')
    ...: 
2.89 ms ± 64.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

#loop solution
In [91]: %%timeit
    ...: df["Flag"] = df.apply(lambda x: "Equal" if x["prod_receipt"] == x["tank_prod"] else ("Not Equal" if x["prod_receipt"] != x["tank_prod"] and  x["tank_prod"] != "No Data" else "No Data"), axis =1)
    ...: 
278 ms ± 7.04 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...