添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
大力的饺子  ·  single sign on - ...·  2 年前    · 

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

14 人关注

我试图根据像这样的数据框架中人的大小来推断分类。

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函数中多个if的帖子。这里有一个例子链接但是,由于某些原因,在多个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

对于潘达斯应用方法中λ函数内的多条if语句,有什么正确的协同方法建议吗?多行或单行的解决方案对我都适用。

4 个评论
你可以直接使用一个函数。
那会是什么样子@AntonvBR?
JAB
@abutremutante 写一个函数来做这个工作,并把名字作为参数传给应用。
你是否看了 pd.cut or 类别 ?
python
pandas
if-statement
lambda
apply
aabujamra
aabujamra
发布于 2018-02-20
4 个回答
Anton vBR
Anton vBR
发布于 2020-06-10
已采纳
0 人赞同

这里有一个小例子,你可以在此基础上继续努力。

基本上, lambda x: x.. 是一个函数的简短单行字。应用程序真正要求的是一个你可以很容易地自己重新创建的函数。

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)

Returns:

        Size Classification
0      80000            <1m
1    8000000          1-10m
2  800000000            N/A
    
我尝试了列出的方法,发现创建你自己的函数是更灵活和透明的方式,可以避免一些意外的后果。
谢谢你,是的,可能是这样的。然而,为了纯粹的性能,应该使用像maxU这样的例子!
MaxU - stop genocide of UA
MaxU - stop genocide of UA
发布于 2020-06-10
0 人赞同

你可以使用 pd.cut function :

bins = [0, 1000000, 10000000, 50000000, ...]
labels = ['<1m','1-10m','10-50m', ...]
df['Classification'] = pd.cut(df['Size'], bins=bins, labels=labels)
    
piRSquared
piRSquared
发布于 2020-06-10
0 人赞同

Using Numpy's 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)]

labels数组的长度比bins的长度大1。 因为当某些东西大于bins的最大值时,searchsorted会返回一个-1。 当我们对labels进行切片时,这就抓住了最后一个标签。

当然好+1,但这里真的需要使用df.assign吗。我的看法是,它的可读性较差。
@AntonvBR 我喜欢 assign 有很多原因。 首先,也是最重要的,因为当OP尝试我的代码时,他们不会自动掐断他们的数据框架。 其次,我更喜欢产生新的数据框架和赋值回名的设计模式。 也就是说,我将展示这两种选择(-。
Victoria
Victoria
发布于 2020-06-10
0 人赞同

应用lambda函数实际上在这里做了工作,我只是想知道问题出在哪里....,因为你的语法看起来很好,而且它能工作....。

df1= [80000, 8000000, 8000000000, 800000000000]
df=pd.DataFrame(df1)
df.columns=['size']