当在所有行中快速应用函数时,如何在numpy中使用if-else

2024-05-20 13:36:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧df_ia:

    dod1    dod2
0   0       0
1   200806  0
2   200806  0
3   200806  0
4   200806  0
5   200806  0
6   200806  0
7   200806  0

以及用于应用于每行的函数:

def life_status(dod1, dod2):
    if dod1.any() == 0:
        ls1 = '1'
    else:
        ls1 = '0'
    if dod2.any() == 0:
        ls2 = '1'
    else:
        ls2 = '0'
    lifestatus = ls1 + ls2
    return lifestatus

df_ia['lifestatus'] = life_status(df_ia['dod1'].values,df_ia['dod2'].values)

但我发现,我不能直接使用:

if dod1.any() to add condition

所以我试了一些类似的方法

if np.any(dod1==0):
   ls1='1'

但它仍然不起作用

输出应如下所示:

    dod1  dod2 lifestatus
0   0       0   11
1   200806  0   01
2   200806  0   01
3   200806  0   01
4   200806  0   01
5   200806  0   01
6   200806  0   01
7   200806  0   01
8   200806  0   01
9   200806  0   01

我可以用这个代码来实现这个

def life_status(row):
    if row['dod1'] == 0:
        ls1 = '1'
    else:
        ls1 = '0'
    if row['dod2'] == 0:
        ls2 = '1'
    else:
        ls2 = '0'
    lifestatus = ls1 + ls2
    return lifestatus
df['lifestatus'] = df.apply(lambda row: life_status(row), axis=1)

但这是非常缓慢的,这就是为什么我张贴这个问题


Tags: dfreturnifdefstatusanyelserow
1条回答
网友
1楼 · 发布于 2024-05-20 13:36:00

解决方案

根据您在评论部分的解释,您以前共享的函数有一个错误的逻辑,这误导了我以前的解决方案。您需要为每一行计算int(dod1[i] == 0) + int(dod2[i] == 0),并返回一个序列或numpy.ndarray

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'dod1': [0] + [200806 for _ in range(7)], 
    'dod2': [0 for _ in range(8)],
})

def life_status(dod1: np.ndarray, dod2: np.ndarray):
    return (dod1 == 0).astype(int).astype(str) + (dod2 == 0).astype(int).astype(str)

life_status(df['dod1'].values, df['dod2'].values)

## Output:
# I will update this later. But the function should work as expected. 

或者,等效地,直接在数据帧上使用它

(df.dod1 == 0).astype(int).astype(str) + (df.dod2 == 0).astype(int).astype(str)

读者注意事项

如果您想使它更通用,例如当(dod1 == 0)为True时,分配4,当它为False时,分配5,您可以按如下操作

# schema:
# - condition: dod1 == 0  > True: 4, False: 5
# - condition: dod1 == 0  > True: 7, False: 8
cond1, cond2 = (df.dod1 == 0), (df.dod2 == 0)
((cond1 * 4 + ~cond1 * 5).astype(str) + (cond2 * 7 + ~cond2 * 8).astype(str)).tolist()

## Output
# ['47', '57', '57', '57', '57', '57', '57', '57']

您可以进一步即兴修改它,并允许根据它是真还是假来替换任何值(strintfloat

(df.dod1 == 0).astype(str).replace({'True': '4', 'False': '5'}) + \
(df.dod2 == 0).astype(str).replace({'True': '7', 'False': '8'})

## Output
# ['47', '57', '57', '57', '57', '57', '57', '57']

相关问题 更多 >