Я получаю: «ValueError: индекс содержит повторяющиеся записи, не может быть изменен»
Данные, с которыми я работаю, очень огромны, я не могу предоставить образцы данных и не могу воспроизвести ошибку. с меньшим набором данных. Я попытался создать дубликаты с фиктивными данными, чтобы воспроизвести мой исходный фрейм, но по какой-то загадочной причине код работает только с фиктивными данными, а не с моими настоящими данными. Вот что я знаю о форме, с которой работаю.
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
Просто чтобы убедиться, что я ' m отбрасываю все дубликаты и оставляю только первый:
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.
EDIT:
Я могу предоставить фиктивные данные, которые должны реплицировать фрейм, над которым я работаю с (всего на пару столбцов меньше, которые не нужны)
df = pd.DataFrame({'name': ["Peter", "Anna", "Anna", "Peter", "Simon", "Johan", "Nils", "Oskar", "Peter"]
, 'Deposits': ["2019-03-07", "2019-03-08", "2019-03-12", "2019-03-12", "2019-03-14", "2019-03-07", "2019-03-08", "2016-03-07", "2019-03-07"]
, 'Withdrawals': ["2019-03-11", "2019-03-19", "2019-05-22", "2019-10-31", "2019-04-05", "2019-03-11", "NaN", "2017-03-06", "2019-03-11"]})
df.duplicated()
0 False
1 False
2 False
.....
7 False
8 True
dtype: bool
df = df.drop_duplicates(keep='first')
df2 = df.melt('name')\
.assign(variable = lambda x: x.variable.map({'Deposits':1,'Withdrawals':-1}))\
.pivot('value','name','variable').fillna(0)\
.rename(columns = lambda c: f'{c} netmov' )
df2 = pd.concat([df2,df2.cumsum().rename(columns = lambda c: c.split()[0] + ' balance')], axis = 1)\
.sort_index(axis=1)
print(df2.head())
name Anna balance Anna netmov Johan balance Johan netmov \
value
2016-03-07 0.0 0.0 0.0 0.0
2017-03-06 0.0 0.0 0.0 0.0
2019-03-07 0.0 0.0 1.0 1.0
2019-03-08 1.0 1.0 1.0 0.0
2019-03-11 1.0 0.0 0.0 -1.0
Это будет работать плавно, даже если в DataFrame есть дубликаты.
Предпочтительно, я не хочу отбрасывать дубликаты тоже, потому что «Анна» могла сделать 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)
)
Тем не менее, наткнитесь на следующую проблему, не связанную с этим. При преобразовании этого DataFrame в json, он по какой-то причине преобразует даты в другой формат.
data = df2.to_json()
print(data)
{
"Peter":
{
"1389744000000": 0,
"1390262400000": 0,
"1390348800000": 0,
"1390521600000": 0,
.....
.....
}
}
Это всегда что-то другое, хех ... приветствую помощь, хотя я почти дотрагиваюсь до цели -стр.