提问者:小点点

透视中的重复值


我有两个数据帧DF1DF2。 一个带有客户债务,另一个带有客户付款日期

我想创建一个新的数据框架,其中包含在支付月份支付的债务的百分比,直到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()

共3个答案

匿名用户

IIUC中,您需要groupby.sumjoincumsum在创建带有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_tableagg_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)