使用apply函数有效,但使用.assign()同一函数无效



我有点卡住了,我有一个可以使用.apply()的工作函数,但我似乎无法让它与.assign()一起工作。我希望这与assign一起使用,这样我就可以将许多转换链接在一起。

有人能为我指出解决这个问题的正确方向吗?

这适用于

data = {'heading': ['some men', 'some men', 'some women']}
dataframe = pd.DataFrame(data=data)
def add_gender(x):
if re.search("(womens?)", x.heading, re.IGNORECASE):
return 'women'
elif re.search("(mens?)", x.heading, re.IGNORECASE):
return 'men'
else:
return 'unisex'
dataframe['g'] = dataframe.apply(lambda ref: add_gender(ref), axis=1)

不起作用

dataframe = dataframe.assign(gender = lambda ref: add_gender(ref))

TypeError:预期字符串或字节,如对象

这是因为.assign()不提供轴参数吗?所以,也许函数没有寻找正确的东西?

在阅读了文档.assign之后,您可以生成一个新列,所以我假设输出与.apply(axis=1)相同

来自DataFrame.assign:的文档

DataFrame.assign(**kwargs(

(…(

参数**kwargs:{str:callable或Series}的dict

列名是关键字如果这些值是可调用的,则在DataFrame上计算这些值并将其分配给新列。可调用程序不能更改输入DataFrame(尽管panda没有检查它(。如果值是不可调用的(例如,系列、标量或数组(,则只分配它们。

这意味着在中

dataframe = dataframe.assign(gender=lambda ref: add_gender(ref))

ref代表调用DataFrame,即dataframe,因此您将整个dataframe传递给函数add_gender。但是,根据定义方式,add_gender希望传递一行(Series对象(作为参数x,而不是整个DataFrame。

if re.search("(womens?)", x.heading, re.IGNORECASE):

assign的情况下,x.heading代表dataframe(x(的整列heading,它是Series对象。然而,re.search仅适用于类似stringbytes的对象,因此会引发错误。而在apply的情况下,x.heading对应于dataframe的每个单独行x的字段heading,其为string值。

要解决此问题,只需将assignapply结合使用即可。请注意,lambda ref: add_gender(ref)中的lambda是多余的,它相当于只传递add_gender

dataframe = dataframe.assign(gender=lambda df: df.apply(add_gender, axis=1))

建议使用Series.str.extractSeries.fillna来定义add_gender

def add_gender(df):
pat = r'b(men|women)s?b'
return df['heading'].str.extract(pat, flags=re.IGNORECASE).fillna('unisex')

关于正则表达式模式'b(men|women)s?b':

  • b匹配单词边界
  • (men|women)menwomen完全匹配并捕获组
  • s?s匹配零次或一次

Series.str.extract提取列heading的每个字符串值的捕获组。不匹配项设置为NaN。然后,Series.fillna将NaN替换为"unisex"。

在这种情况下,add_gender期望通过整个DataFrame。有了这个定义,你可以简单地进行

dataframe = dataframe.assign(gender=add_gender)

设置:

import pandas as pd
import re
data = {'heading': ['some men', 'some men', 'some women', 'x mens', 'y womens',  'other', 'blahmenblah', 'blahwomenblah']}
dataframe = pd.DataFrame(data=data)
def add_gender(df):
pat = r'b(men|women)s?b'
return df['heading'].str.extract(pat, flags=re.IGNORECASE).fillna('unisex')

输出:

>>> dataframe 
heading
0       some men
1       some men
2     some women
3         x mens
4       y womens
5          other
6    blahmenblah
7  blahwomenblah
>>> dataframe = dataframe.assign(gender = add_gender)
>>> dataframe 
heading  gender
0       some men     men
1       some men     men
2     some women   women
3         x mens     men
4       y womens   women
5          other  unisex
6    blahmenblah  unisex
7  blahwomenblah  unisex

相关内容

  • 没有找到相关文章

最新更新