数据框是否有多列映射函数?
在Pandas中,
怎么从多个列中派生出一列呢?
举个例子,假设我想给我的数据集加上每个主题的正确称呼。也许是为了给一些图表加标签,这样我就能知道结果是针对谁的。
假设有一个数据集:
data = [('male', 'Homer', 'Simpson'), ('female', 'Marge', 'Simpson'), ('male', 'Bart', 'Simpson'),('female', 'Lisa', 'Simpson'),('infant', 'Maggie', 'Simpson')]
people = pd.DataFrame(data, columns=["gender", "first_name", "last_name"])
所以我们有:
gender first_name last_name
0 male Homer Simpson
1 female Marge Simpson
2 male Bart Simpson
3 female Lisa Simpson
4 infant Maggie Simpson
还有一个函数,我想把它应用到每一行,并把结果存储到一个新列里。
def get_address(gender, first, last):
title=""
if gender=='male':
title='Mr'
elif gender=='female':
title='Ms'
if title=='':
return first + ' '+ last
else:
return title + ' ' + first[0] + '. ' + last
目前我的方法是:
people['address'] = map(lambda row: get_address(*row),people.get_values())
gender first_name last_name address
0 male Homer Simpson Mr H. Simpson
1 female Marge Simpson Ms M. Simpson
2 male Bart Simpson Mr B. Simpson
3 female Lisa Simpson Ms L. Simpson
4 infant Maggie Simpson Maggie Simpson
这个方法可以用,但看起来不太优雅。感觉把数据转换成没有索引的列表,然后再赋值回有索引的列,有点不太好。
2 个回答
1
你可以在不使用显式循环的情况下做到这一点:
In [70]: df
Out[70]:
gender first_name last_name
0 male Homer Simpson
1 female Marge Simpson
2 male Bart Simpson
3 female Lisa Simpson
4 infant Maggie Simpson
In [71]: title = df.gender.replace({'male': 'Mr', 'female': 'Ms', 'infant': ''})
In [72]: initial = np.where(df.gender != 'infant', df.first_name.str[0] + '. ', df.first_name + ' ')
In [73]: initial
Out[73]: array(['H. ', 'M. ', 'B. ', 'L. ', 'Maggie '], dtype=object)
In [74]: address = (title + ' ' + Series(initial) + df.last_name).str.strip()
In [75]: address
Out[75]:
0 Mr H. Simpson
1 Ms M. Simpson
2 Mr B. Simpson
3 Ms L. Simpson
4 Maggie Simpson
dtype: object
可以看看关于Series.str
方法的文档,这些方法非常棒。str
中的大多数方法都很实用,还有一些额外的功能,比如extract
。
2
你需要使用的是 apply(func,axis=1)
这个方法。它会对你的数据表中的每一行应用一个函数。
在你的例子中,把你的方法 get_address 修改为...
def get_address(row):#row is a pandas series with col names as indexes
title=""
gender = row['gender'] #extract gender from pandas series
first = row['first_name'] #extract firstname from pandas series
second = row['last_name'] #extract lastname from pandas series
if gender=='male':
title='Mr'
elif gender=='female':
title='Ms'
if title=='':
return first + ' '+ last
else:
return title + ' ' + first[0] + '. ' + last
然后调用 people.apply(get_address,axis=1)
,这个操作会返回一个新的列(实际上这是一个 pandas 的系列,带有正确的索引,这样数据表就知道如何正确地把它加到列里)。要把这个新列加到你的数据表中,添加以下代码...
people['address'] = people.apply(get_address,axis=1)