如何解决 ValueError:无法从重复轴重新索引
Posted
技术标签:
【中文标题】如何解决 ValueError:无法从重复轴重新索引【英文标题】:How to resolve ValueError: cannot reindex from a duplicate axis 【发布时间】:2021-10-03 23:21:53 【问题描述】:输入
Client | First name | Last Name | Start Date | End Date | Amount | Invoice Date |
---|---|---|---|---|---|---|
XXX | John | Kennedy | 15-01-2021 | 28-02-2021 | 137,586.00 | 20-04-2021 |
YYY | Peter | Paul | 7-02-2021 | 31-03-2021 | 38,750.00 | 20-04-2021 |
ZZZ | Michael | K | 10-03-2021 | 29-04-2021 | 137,586.00 | 30-04-2021 |
代码
df = pd.read_excel ('file.xlsx',parse_dates=['Start Date','End Date'] )
df['Start Date'] = pd.to_datetime(df['Start Date'],format='%d-%m-%Y')
df['End Date'] = pd.to_datetime(df['End Date'],format='%d-%m-%Y')
df['r'] = df.apply(lambda x: pd.date_range(x['Start Date'],x['End Date']), axis=1)
df = df.explode('r')
print(df)
months = df['r'].dt.month
starts, ends = months.ne(months.groupby(level=0).shift(1)), months.ne(months.groupby(level=0).shift(-1))
df2 = pd.DataFrame('First Name': df['First name'],
'Start Date': df.loc[starts, 'r'].dt.strftime('%Y-%m-%d'),
'End Date': df.loc[ends, 'r'].dt.strftime('%Y-%m-%d'),
'Date Diff': df.loc[ends, 'r'].dt.strftime('%d').astype(int)-df.loc[starts, 'r'].dt.strftime('%d').astype(int)+1)
df = df.loc[~df.index.duplicated(), :]
df2 = pd.merge(df, df2, left_index=True, right_index=True)
df2['Amount'] = df['Amount'].mul(df2['Date_Diff'])
print(df['Amount'])
print (df)
df.to_excel('report.xlsx', index=True)
错误 ValueError:无法从重复的轴重新索引
预期输出
如何解决这个问题?
【问题讨论】:
这能回答你的问题吗? What does `ValueError: cannot reindex from a duplicate axis` mean? 【参考方案1】:首先在您的输入 Excel 文件中进行一些更正,即更改名字 到 First Name - 大写“N”,就像在其他列中一样。
然后,要读取您的 Excel 文件,运行就足够了:
df = pd.read_excel('Input.xlsx', parse_dates=['Start Date', 'End Date',
'Invoice Date'], dayfirst=True)
无需调用to_datetime。
还要注意,由于 Invoice Date 也包含日期,因此我将此列添加到 parse_dates 列表。
然后定义两个函数:
获取当前行每月数据的函数:
def getMonthData(grp, amnt, dayNo):
return pd.Series([grp.min(), grp.max(), amnt * grp.size / dayNo],
index=['Start Date', 'End Date', 'Amount'])
它将输入的日期系列(单月)转换为“新”内容 输出行(开始/结束日期和总额的适当份额,要 占本月)。
它将在以下函数中调用。
一个“爆炸”当前行的函数:
def rowExpl(row):
ind = pd.date_range(row['Start Date'], row['End Date']).to_series()
rv = ind.groupby(pd.Grouper(freq='M')).apply(getMonthData,
amnt=row.Amount, dayNo=ind.size).unstack().reset_index(drop=True)
rv.insert(0, 'Client', row.Client)
rv.insert(1, 'First Name', row['First Name'])
rv.insert(2, 'Last Name', row['Last Name'])
return rv.assign(**'Invoice Date': row['Invoice Date'])
最后一步是得到结果。将 rowExpl 应用于每一行并连接 部分结果到单个输出 DataFrame 中:
result = pd.concat(df.apply(rowExpl, axis=1).values, ignore_index=True)
您的数据样本的结果是:
Client First Name Last Name Start Date End Date Amount Invoice Date
0 XXX John Kennedy 2021-01-15 2021-01-31 51976.9 2021-04-20
1 XXX John Kennedy 2021-02-01 2021-02-28 85609.1 2021-04-20
2 YYY Peter Paul 2021-02-07 2021-02-28 16084.9 2021-04-20
3 YYY Peter Paul 2021-03-01 2021-03-31 22665.1 2021-04-20
4 ZZZ Michael K 2021-03-10 2021-03-31 59350.8 2021-04-30
5 ZZZ Michael K 2021-04-01 2021-04-29 78235.2 2021-04-30
不要对 Amount 列看似太低的精度感到不满。 这只是 Jupyter Notebook 显示 DataFrame 的方式。
当你运行result.iloc[0, 5]
,你会得到:
51976.933333333334
具有完整的、实际上保持的精确度。
【讨论】:
VaIdi_Bo 尝试执行该函数,但输出为空白 如果你执行了 result = pd.concat(…) 那么实际结果在 result 变量中。要查看此结果,请执行例如打印(结果)。还要检查文件名(这个文件是否实际包含预期的数据)。 另一项检查:不是从 Excel 文件中读取,而是从例如加载数据。 CSV 文件,然后执行我的代码。以上是关于如何解决 ValueError:无法从重复轴重新索引的主要内容,如果未能解决你的问题,请参考以下文章
Pandas - ValueError:无法从重复的轴重新索引
ValueError:groupby Pandas 中的“无法从重复的轴重新索引”
Pandas - 在数据框中附加字符串:ValueError:无法从重复的轴重新索引