Python 3.x 熊猫在下降后复制了索引
我得到:“ValueError:索引包含重复的条目,无法重塑” 我处理的数据非常庞大,我无法提供样本数据,也无法用较小的数据集复制错误。我曾尝试使用虚拟数据生成副本以复制我的原始帧,但出于某种神秘的原因,代码仅适用于虚拟数据,而不适用于我的真实数据。这就是我所知道的我正在使用的形状Python 3.x 熊猫在下降后复制了索引,python-3.x,pandas,duplicates,pivot,Python 3.x,Pandas,Duplicates,Pivot,我得到:“ValueError:索引包含重复的条目,无法重塑” 我处理的数据非常庞大,我无法提供样本数据,也无法用较小的数据集复制错误。我曾尝试使用虚拟数据生成副本以复制我的原始帧,但出于某种神秘的原因,代码仅适用于虚拟数据,而不适用于我的真实数据。这就是我所知道的我正在使用的形状 df.shape >> (6820, 26) df.duplicated() >> 0 False >> 1 False >> 2
df.shape
>> (6820, 26)
df.duplicated()
>> 0 False
>> 1 False
>> 2 False
>> ...
>> 6818 False
>> 6819 False
>> Length: 6820, dtype: bool
现在我想找出哪些行是重复的
df[df.duplicated(keep=False)]
>> 0 rows × 26 columns
为了确保我删除了所有副本,只保留第一个副本:
df = df.drop_duplicates(keep='first')
这就是我得到ValueError的时候:
df2 = df.melt('Release')\
.assign(variable = lambda x: x.variable.map({'Created Date':1,'Finished Date':-1}))\
.pivot('value','Release','variable').fillna(0)\
.rename(columns = lambda c: f'{c} netmov' )
---> 33 .pivot('value','Release','variable').fillna(0)\
ValueError: Index contains duplicate entries, cannot reshape
通过进一步研究,似乎重复的不是行,而是索引。我尝试用df.reset_index()重置索引,但它抛出相同的ValueError
编辑:
我可以提供虚拟数据来复制我正在使用的框架(只需少几个不需要的列)
这将平稳运行,即使数据帧中存在重复项
最好我也不想丢弃副本,因为“安娜”一天可以存4次款,取4次款,所以我想数一数
我正在使用的数据帧:
df = df.drop_duplicates().reset_index(drop=True)
df = df.drop(['id'], axis=1)
df
Output:
name Deposits Withdrawals
0 Anna 2020-07-31 NaN
1 Peter 2020-07-30 NaN
2 Simon 2020-07-30 NaN
3 Simon 2020-07-29 NaN
4 Simon 2020-07-29 NaN
... ... ... ...
6154 Peter 2014-01-22 2014-02-03
6155 Peter 2014-01-22 2014-01-29
6156 Peter 2014-01-22 2014-01-24
6157 Peter 2014-01-21 2014-01-29
6158 Peter 2014-01-15 2014-02-03
6159 rows × 3 columns
更新:向社区大声呼喊,帮助我解决这个问题
这解决了问题:
df.Deposits = pd.to_datetime(df.Deposits)
df.Withdrawals = pd.to_datetime(df.Withdrawals)
df2 = (
df.melt('name')
.assign(variable = lambda x: x.variable.map({'Deposits':1,'Withdrawals':-1}))
.dropna(subset=['value']) # you need this for cases like Nils's Withdrawal
)
df2 = df2.groupby(['value', 'name']).sum().unstack(fill_value=0).droplevel(0, axis=1)
df2 = (
pd.concat([df2, df2.cumsum()], keys=['netmov', 'balance'], axis=1)
notice how concat has the functionality you want for naming columns
and is a better idea to have netmov/balance in a separate level
in case you want to groupby or .loc later on
.reorder_levels([1, 0], axis=1).sort_index(axis=1)
)
不过,偶然发现了下一个问题,与此无关。当将此数据帧转换为json时,出于某种原因,它会将日期转换为另一种格式
data = df2.to_json()
print(data)
{
"Peter":
{
"1389744000000": 0,
"1390262400000": 0,
"1390348800000": 0,
"1390521600000": 0,
.....
.....
}
}
总是有别的事,呵呵。。为帮助干杯,我几乎可以触到目标线。问题似乎出现在一个名字在完全相同的存款/取款日期有多个移动时(因此重复)。Dataframe
.pivot
方法无法处理重复的索引,只是它不是为此而设计的。出于分析的目的,.pivot\u table
将实现这一技巧,主要区别在于此表可以应用聚合函数来处理重复索引(在本例中为sum)
我个人倾向于使用.groupby
处理任何此类问题,因为它不仅提供了按df中任何列组合进行分组的功能,还可以包括外部序列、计算、索引或自身或其他索引级别、掩码等
所以我的代码是:
df.Deposits = pd.to_datetime(df.Deposits)
df.Withdrawals = pd.to_datetime(df.Withdrawals) # this parsing probably happens in read_csv
df2 = (
df.melt('name')
.assign(variable = lambda x: x.variable.map({'Deposits':1, 'Withdrawals':-1}))
# use lambda if you must
# replace on 'variable' after creating df2 would also work
# and is probably faster for larger dfs
.dropna(subset=['value']) # you need this for cases like Nils's Withdrawal
)
df2 = df2.groupby(['value', 'name']).sum().unstack(fill_value=0).droplevel(0, axis=1)
df2 = (
pd.concat([df2, df2.cumsum()], keys=['netmov', 'balance'], axis=1)
# notice how concat has the functionality you want for naming columns
# and is a better idea to have netmov/balance in a separate level
# in case you want to groupby or .loc later on
.reorder_levels([1, 0], axis=1).sort_index(axis=1)
)
输出
name Anna Johan Nils ... Oskar Peter Simon
balance netmov balance netmov balance ... netmov balance netmov balance netmov
value ...
2016-03-07 0 0 0 0 0 ... 1 0 0 0 0
2017-03-06 0 0 0 0 0 ... -1 0 0 0 0
2019-03-07 0 0 1 1 0 ... 0 2 2 0 0
2019-03-08 1 1 1 0 1 ... 0 2 0 0 0
2019-03-11 1 0 0 -1 1 ... 0 0 -2 0 0
2019-03-12 2 1 0 0 1 ... 0 1 1 0 0
2019-03-14 2 0 0 0 1 ... 0 1 0 1 1
2019-03-19 1 -1 0 0 1 ... 0 1 0 1 0
2019-04-05 1 0 0 0 1 ... 0 1 0 0 -1
2019-05-22 0 -1 0 0 1 ... 0 1 0 0 0
2019-10-31 0 0 0 0 1 ... 0 0 -1 0 0
当一个名字在完全相同的存款/取款日期(因此是重复的)有多个移动时,问题似乎就出现了。Dataframe
.pivot
方法无法处理重复的索引,只是它不是为此而设计的。出于分析的目的,.pivot\u table
将实现这一技巧,主要区别在于此表可以应用聚合函数来处理重复索引(在本例中为sum)
我个人倾向于使用.groupby
处理任何此类问题,因为它不仅提供了按df中任何列组合进行分组的功能,还可以包括外部序列、计算、索引或自身或其他索引级别、掩码等
所以我的代码是:
df.Deposits = pd.to_datetime(df.Deposits)
df.Withdrawals = pd.to_datetime(df.Withdrawals) # this parsing probably happens in read_csv
df2 = (
df.melt('name')
.assign(variable = lambda x: x.variable.map({'Deposits':1, 'Withdrawals':-1}))
# use lambda if you must
# replace on 'variable' after creating df2 would also work
# and is probably faster for larger dfs
.dropna(subset=['value']) # you need this for cases like Nils's Withdrawal
)
df2 = df2.groupby(['value', 'name']).sum().unstack(fill_value=0).droplevel(0, axis=1)
df2 = (
pd.concat([df2, df2.cumsum()], keys=['netmov', 'balance'], axis=1)
# notice how concat has the functionality you want for naming columns
# and is a better idea to have netmov/balance in a separate level
# in case you want to groupby or .loc later on
.reorder_levels([1, 0], axis=1).sort_index(axis=1)
)
输出
name Anna Johan Nils ... Oskar Peter Simon
balance netmov balance netmov balance ... netmov balance netmov balance netmov
value ...
2016-03-07 0 0 0 0 0 ... 1 0 0 0 0
2017-03-06 0 0 0 0 0 ... -1 0 0 0 0
2019-03-07 0 0 1 1 0 ... 0 2 2 0 0
2019-03-08 1 1 1 0 1 ... 0 2 0 0 0
2019-03-11 1 0 0 -1 1 ... 0 0 -2 0 0
2019-03-12 2 1 0 0 1 ... 0 1 1 0 0
2019-03-14 2 0 0 0 1 ... 0 1 0 1 1
2019-03-19 1 -1 0 0 1 ... 0 1 0 1 0
2019-04-05 1 0 0 0 1 ... 0 1 0 0 -1
2019-05-22 0 -1 0 0 1 ... 0 1 0 0 0
2019-10-31 0 0 0 0 1 ... 0 0 -1 0 0
你能举例说明你的数据/数据帧结构是什么样的吗?你有没有试过使用
.reset_index()
以防万一?是的,我试过一些变体:df=df.drop_duplicates(keep='first')。reset_index()with drop和inplace df=df。reset_index(drop=True)with drop和inplace我正在从csv文件读取数据,共有26列,但我正在尝试创建的与此时间线相关的唯一列是:[id']、['name']、['depositions']、['drawings']。在示例数据中,我从原始csv文件中获取数据。此csv文件在['id']-列中还包含多个id相同的行。我正在删除的那些。你能提供一个数据/数据帧结构的示例吗?你是否尝试过使用.reset_index()
以防万一?是的,我尝试过一些变体:df=df.drop_duplicates(keep='first')。用drop和inplace df=df.reset_index()重置_索引(drop=True)使用drop和INPLACE,我从csv文件中读取数据,共有26列,但我尝试创建的唯一与此时间线相关的列是:['id']、['name']、['Deposits']、['Drawits']、['Drawits']。在示例数据中,我从原始csv文件中获取数据。此csv文件在['id']-列中还包含多个id相同的行。我要扔的那些。再一次,你救了我一天(一周)!这个很好用!我用netmov删除了最后一部分,但是检查值是一个很好的特性。现在我要弄清楚为什么日期在转换成json时会有一个奇怪的值。data=df2.to_json()将日期转换为另一种格式。{“Peter”:{“138974400000”:0,“1390262400000”:0,“1390348800000”:0,…}再次感谢您的帮助,向上投票!您可以将dateformat参数传递到到_json
,再次,您救了我一天(一周)!这很好!我用netmov删除了最后一部分,但是检查值是一个很好的功能。现在我只需要弄清楚为什么转换为json时日期会有一个奇怪的值。data=df2。to_json()将日期转换为另一种格式。{“Peter”:{“138974400000”:0,“1390262400000”:0,“1390348800000”:0,…}再次感谢您的帮助,向上投票!您可以将dateformat参数传递给传递给\u json