在Pandas中使用Apply Lambda函数和多个if语句

2024-05-15 20:34:21 发布

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

我试着根据像这样的数据框中一个人的大小推断出一个分类:

      Size
1     80000
2     8000000
3     8000000000
...

我希望它看起来像这样:

      Size        Classification
1     80000       <1m
2     8000000     1-10m
3     8000000000  >1bi
...

我知道理想的过程是应用这样的lambda函数:

df['Classification']=df['Size'].apply(lambda x: "<1m" if x<1000000 else "1-10m" if 1000000<x<10000000 else ...)

我检查了一些关于lambda函数here is an example link中多个ifs的帖子,但是synthax在多个ifs语句中由于某些原因不适合我,但它在一个if条件下工作。

所以我尝试了这个“非常优雅”的解决方案:

df['Classification']=df['Size'].apply(lambda x: "<1m" if x<1000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "1-10m" if 1000000 < x < 10000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "10-50m" if 10000000 < x < 50000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "50-100m" if 50000000 < x < 100000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "100-500m" if 100000000 < x < 500000000 else pass)
df['Classification']=df['Size'].apply(lambda x: "500m-1bi" if 500000000 < x < 1000000000 else pass)
df['Classification']=df['Size'].apply(lambda x: ">1bi" if 1000000000 < x else pass)

计算出“pass”似乎也不适用于lambda函数:

df['Classification']=df['Size'].apply(lambda x: "<1m" if x<1000000 else pass)
SyntaxError: invalid syntax

对于Pandas中apply方法中lambda函数中的multiple if语句,有什么关于synthax的正确建议吗?不管是多行还是单行解决方案对我都有效。


Tags: 数据lambda函数dfsizeif分类pass
3条回答

下面是一个小示例,您可以在此基础上进行构建:

基本上,lambda x: x..是函数的短一行。apply真正需要的是一个功能,您可以轻松地重新创建自己。

import pandas as pd

# Recreate the dataframe
data = dict(Size=[80000,8000000,800000000])
df = pd.DataFrame(data)

# Create a function that returns desired values
# You only need to check upper bound as the next elif-statement will catch the value
def func(x):
    if x < 1e6:
        return "<1m"
    elif x < 1e7:
        return "1-10m"
    elif x < 5e7:
        return "10-50m"
    else:
        return 'N/A'
    # Add elif statements....

df['Classification'] = df['Size'].apply(func)

print(df)

返回:

        Size Classification
0      80000            <1m
1    8000000          1-10m
2  800000000            N/A

您可以使用^{} function

bins = [0, 1000000, 10000000, 50000000, ...]
labels = ['<1m','1-10m','10-50m', ...]

df['Classification'] = pd.cut(df['Size'], bins=bins, labels=labels)

使用Numpy的searchsorted

labels = np.array(['<1m', '1-10m', '10-50m', '>50m'])
bins = np.array([1E6, 1E7, 5E7])

# Using assign is my preference as it produces a copy of df with new column
df.assign(Classification=labels[bins.searchsorted(df['Size'].values)])

如果要在现有数据帧中生成新列

df['Classification'] = labels[bins.searchsorted(df['Size'].values)]

一些解释

来自Docs:^{}

Find indices where elements should be inserted to maintain order.

Find the indices into a sorted array a such that, if the corresponding elements in v were inserted before the indices, the order of a would be preserved.

labels数组的长度比bins数组的长度大一倍。因为当某个值大于bins中的最大值时,searchsorted返回-1。当我们切片labels时,这将获取最后一个标签。

相关问题 更多 >