我正在处理Titanic数据集
可以为多名乘客发行一张票,即e。几个乘客可能有相同的机票号
所有这些乘客的“票价”功能将相同,并且等于整个票价
例如,如果有4位乘客乘一张机票旅行,则票价可以是40美元,但每位乘客票价应为10美元。
因此,应该将机票价格除以机票频率以计算每位乘客的票价。
但是还有一件事:婴儿需要支付2美元,而12岁以下的儿童则需要支付成人一半的费用。
因此,我试图在考虑儿童票价的情况下计算出每个成年人在机票中支付的价格。
这是一个示例数据框:
df = pd.DataFrame({'Age': [0.5,5,20,21,22,23,24], 'Fare': [17,17,17,40,40,40,40], 'TicketNum': [1,1,1,2,2,2,2]})
Age Fare TicketNum
0 0.5 17 1
1 5.0 17 1
2 20.0 17 1
3 21.0 40 2
4 22.0 40 2
5 23.0 40 2
6 24.0 40 2
首先,我要执行此功能:
def fare_calc(x):
ticket_fare = x['Fare'].mean()
group_size = x.shape[0]
babies_count = x[x['Age']<1].count()
child_count = x[x['Age']<12].count()
adult_count = group_size - babies_count - child_count
adult_fare = (ticket_fare - babies_count * 2) / (adult_count + child_count*0.5)
return adult_fare
然后我尝试:
df['TicketFreq'] = df.groupby('TicketNum')['TicketNum'].transform('count')
df['Fare2'] = df[df.TicketFreq>1].groupby(['TicketNum'])['Age','Fare'].agg(fare_calc)
并得到一个错误:
ValueError:传递的项目数错误2,展示位置表示1
所需的输出如下:
Age Fare TicketNum Fare2
0 0.5 17 1 10
1 5.0 17 1 10
2 20.0 17 1 10
3 21.0 40 2 10
4 22.0 40 2 10
5 23.0 40 2 10
6 24.0 40 2 10
答案 0 :(得分:1)
嘿,您的公式编制者似乎错了,但是当您用fare_calc
替换.agg
调用并删除您指定的两列时,.apply
函数就会执行。参见下面的示例
df[df.TicketFreq>1].groupby(['TicketNum']).apply(fare_calc)
此外,您的功能仅需要进行一些更改。
要获取babie_count和child_count的数字计数,您需要指定一个列以仅获取一个整数
def fare_calc(x):
ticket_fare = x['Fare'].mean()
group_size = x.shape[0]
babies_count = x[x['Age']<1]['Age'].count()
child_count = x[x['Age']<12]['Age'].count()
adult_count = group_size - babies_count - child_count
adult_fare = (ticket_fare - babies_count * 2) / (adult_count + child_count * 0.5)
return adult_fare
答案 1 :(得分:1)
这是我的解决方法
我使用pd.Series()
和.repeat()
函数创建按列的一系列值。
顺便说一句,您忘记了使用(df['Age']<12) & (df['Age']>1)
从child_count中排除babies_count
def fare_calc(x):
group_size = x.shape[0]
ticket_fare = pd.Series(x['Fare'].mean().repeat(group_size))
babies_count = x[x['Age']<1 ]['Age'].count()
child_count = x[(df['Age']<12) & (df['Age']>1)]['Age'].count()
adult_count = group_size - babies_count - child_count
adult_fare = (ticket_fare - babies_count * 2) / (adult_count + child_count * 0.5)
return adult_fare
最后,仅使用apply
提取由.values
函数创建的堆叠Series的值,以防止发生“不兼容索引” TypeError。
df['Fare2'] = df[df.TicketFreq>1].groupby(['TicketNum']).apply(fare_calc).values
print(df)
Age Fare TicketNum TicketFreq Fare2
0 0.5 17 1 3 10.0
1 5.0 17 1 3 10.0
2 20.0 17 1 3 10.0
3 21.0 40 2 4 10.0
4 22.0 40 2 4 10.0
5 23.0 40 2 4 10.0
6 24.0 40 2 4 10.0
编辑1:前一个功能的直观版本:
import pandas as pd
df = pd.DataFrame({'Age': [0.5,5,20,21,22,23,24], 'Fare': [17,17,17,40,40,40,40], 'TicketNum': [1,1,1,2,2,2,2]})
df['TicketFreq'] = df.groupby('TicketNum')['TicketNum'].transform('count')
def fare_calc(x):
group_size = x.shape[0]
x['ticket_fare'] = x['Fare'].mean()
babies_count = x[x['Age']<1 ]['Age'].count()
child_count = x[(df['Age']<12) & (df['Age']>1)]['Age'].count()
adult_count = group_size - babies_count - child_count
x['adult_fare'] = (x['ticket_fare'] - babies_count * 2) / (adult_count + child_count * 0.5)
return x['adult_fare']
df['Fare2'] = df[df.TicketFreq>1].groupby(['TicketNum']).apply(fare_calc).values
print(df)
Age Fare TicketNum TicketFreq Fare2
0 0.5 17 1 3 10.0
1 5.0 17 1 3 10.0
2 20.0 17 1 3 10.0
3 21.0 40 2 4 10.0
4 22.0 40 2 4 10.0
5 23.0 40 2 4 10.0
6 24.0 40 2 4 10.0
编辑2:在函数内部直接创建“ Fare2”的地方更简单
import pandas as pd
df = pd.DataFrame({'Age': [0.5,5,20,21,22,23,24], 'Fare': [17,17,17,40,40,40,40], 'TicketNum': [1,1,1,2,2,2,2]})
df['TicketFreq'] = df.groupby('TicketNum')['TicketNum'].transform('count')
def fare_calc(x):
group_size = x.shape[0]
ticket_fare = x['Fare'].mean()
babies_count = x[x['Age']<1 ]['Age'].count()
child_count = x[(df['Age']<12) & (df['Age']>1)]['Age'].count()
adult_count = group_size - babies_count - child_count
x['Fare2'] = (ticket_fare - babies_count * 2) / (adult_count + child_count * 0.5)
return x
df = df[df.TicketFreq>1].groupby(['TicketNum']).apply(fare_calc)
print(df)
Age Fare TicketNum TicketFreq Fare2
0 0.5 17 1 3 10.0
1 5.0 17 1 3 10.0
2 20.0 17 1 3 10.0
3 21.0 40 2 4 10.0
4 22.0 40 2 4 10.0
5 23.0 40 2 4 10.0
6 24.0 40 2 4 10.0
答案 2 :(得分:0)
一个较小但紧迫的问题是,在您的最后一行代码中,['Age', 'Fare']
应该为[['Age', 'Fare']]
,因为您希望使用列名列表进行索引。
主要问题是您编写了fare_calc()
才能在整个DataFrame上工作,但是传递给df.agg()
的函数将分别应用于每个列。