我有两个数据帧DF1
和DF2
。 一个带有客户债务
,另一个带有客户付款
和日期
。
我想创建一个新的数据框架,其中包含在支付月份支付的债务的百分比,直到01-2017
。
问题是,一些客户在同一个月支付了两次,因此存在重复值,数据透视无法按这种方式运行,它显示:valueerror:Index包含重复条目,无法重新塑造
我该如何解决这个问题?
谢谢你抽出时间!
import pandas as pd
d1 = {'client number': ['2', '2','3','6','7','7','8','8','8','8','8','8','8','8'],
'month': [1, 2, 3,1,10,12,3,5,8,1,1,4,5,8],
'year':[2013,2013,2013,2019,2013,2013,2013,2013,2013,2014,2014,2015,2016,2017],
'payment' :[100,100,200,10000,200,100,300,500,200,100,200,200,500,50]}
df1 = pd.DataFrame(data=d1).set_index('client number')
d2 = {'client number': ['2','3','6','7','8'],
'debt': [200, 600,10000,300,3000]}
df2 = pd.DataFrame(data=d2)
df2 = df2.set_index('client number')
df1['pct'] = df1['payment'].div(df1.index.map(df2['debt'])).round(2)
df1['date'] = df1['year'].astype(str) + '-' + df1['month'].astype(str).str.zfill(2)
df3 = df2.join(df1.pivot(columns='date', values='pct').fillna(0)).reset_index()
IIUC中,您需要groupby.sum
,join
cumsum
在创建带有pd.crosstab
的枢轴数据框架之前获取总数的滚动百分比
df1a = (
df1.groupby(["client number", "month", "year"])["payment"]
.sum()
.to_frame("payment")
.join(df2)
.reset_index([1, 2])
)
df1a = df1a.assign(
cumulativePerc=(
df1a.groupby(level=0)["payment"].cumsum() / df1a["debt"] * 100
).round(2)
)
final = (
pd.crosstab(
df1a.index,
[df1a["year"], df1a["month"]],
df1a["cumulativePerc"],
aggfunc="first",
).fillna(0)
).rename_axis("client number")
print(final)
year 2013 2014 2015 \
month 1 2 3 5 8 10 12 1 4
client number
2 50.0 100.0 0.00 0.00 0.00 0.00 0.0 0.0 0.00
3 0.0 0.0 33.33 0.00 0.00 0.00 0.0 0.0 0.00
6 0.0 0.0 0.00 0.00 0.00 0.00 0.0 0.0 0.00
7 0.0 0.0 0.00 0.00 0.00 66.67 100.0 0.0 0.00
8 0.0 0.0 20.00 43.33 66.67 0.00 0.0 10.0 26.67
year 2016 2017 2019
month 5 8 1
client number
2 0.0 0.00 0.0
3 0.0 0.00 0.0
6 0.0 0.00 100.0
7 0.0 0.00 0.0
8 60.0 68.33 0.0
使用dataframe.pivot_table
和agg_func='sum'
,因为可以添加每月偿还债务的分数:
df3 = (
df2.join(
df1.pivot_table(index=df1.index, columns='date', values='pct', aggfunc='sum').fillna(0))
.reset_index()
)
结果:
# print(df3)
client number debt 2013-01 2013-02 2013-03 2013-05 2013-08 2013-10 2013-12 2014-01 2015-04 2016-05 2017-08 2019-01
0 2 200 0.5 0.5 0.00 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.0
1 3 600 0.0 0.0 0.33 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.0
2 6 10000 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 1.0
3 7 300 0.0 0.0 0.00 0.00 0.00 0.67 0.33 0.0 0.00 0.00 0.00 0.0
4 8 3000 0.0 0.0 0.10 0.17 0.07 0.00 0.00 0.1 0.07 0.17 0.02 0.0
您可以改用pivot_table
。 这允许您应用一个函数来聚合重复的条目。 例如,可以取重复值的最大值。 此外,似乎您应该在此函数调用中包含index
参数。 将原始的pivot
调用替换为:
df1.pivot_table(columns='date', index='client number', values='pct', aggfunc='max').fillna(0)