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

Posted

技术标签:

【中文标题】快速在所有行中应用函数时如何在pandas numpy中使用if else【英文标题】:How to use if else in pandas numpy when apply function in all the rows fast 【发布时间】:2021-09-23 00:09:54 【问题描述】:

我有一个数据框 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)

但这很慢,这就是我发布这个问题的原因。

【问题讨论】:

(dod1 == 0).any() ? @William 我认为你想要的就是 Psidom 提到的。是吗?你写life_status()的逻辑伪代码怎么样? 嗨@Psidom你能帮我解决这个非常相似的问题吗:***.com/questions/68371165/… 【参考方案1】:

解决方案

根据您在评论部分的解释,您之前共享的函数逻辑错误,这误导了我之前的解决方案。您需要为每一行评估 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)根据它是 True 还是 False 来替换。

(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']

【讨论】:

@William 请看看这个,如果您有任何问题,请告诉我。另外,请提供你的函数life_status()的逻辑,因为你可能没有正确实现它。 嗨@CypherX 你能帮我解决这个非常相似的问题吗:***.com/questions/68371165/… @William 我刚刚发布了您其他问题的答案。 这个答案不起作用我刚刚检查过,因为如果只返回它看起来的第一个条件。 请写下你的函数逻辑。

以上是关于快速在所有行中应用函数时如何在pandas numpy中使用if else的主要内容,如果未能解决你的问题,请参考以下文章

pandas删除数据行中的重复数据行基于dataframe所有列删除重复行基于特定数据列或者列的作何删除重复行删除重复行并保留重复行中的最后一行pandas删除所有重复行(不进行数据保留)

在 Pandas 中使用 group by 时如何将“first”和“last”函数应用于列?

如何在 Pandas 数据框中按行值对日期时间列进行排序?

Python3快速入门(十五)——Pandas数据处理

如何检查一系列字符串是不是包含在 PANDAS DataFrame 列中并将该字符串分配为行中的新列?

如何使用 Pandas 计算跨多列的行中的值?