如何解决“正在尝试从DataFrame的切片副本上设置值”?

时间:2019-11-09 21:07:50

标签: python pandas dataframe

我有以下代码:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import csv
headers = ['ticker', 'size', 'price', 'unix','type','time']
dtypes = {'ticker': 'str', 'size': 'float', 'price': 'float', 'unix': 'float','type': 'str','time': 'str'}
parse_dates = ['time']
btcnow = pd.read_csv('new 113-115.csv', header=None, names=headers, dtype=dtypes, parse_dates=parse_dates)
now3 = pd.DataFrame(btcnow, columns=['size','time','unix','price'])

now4=now3[['time','price','size']]
df6= now4.loc[now4["size"] == 4,'size']
df7= now4.loc[now4["size"] == 4, "time"]
df8= now4.loc[now4["size"] == 4, "price"]
result1= [df6,df7,df8]

result1 = pd.concat(result1, axis=1, sort=True)

result1.columns = ['size','orig_time','price']
df10=result1.groupby('orig_time').last().reset_index()
df10 = df10[['size','orig_time','price']]

from datetime import datetime, timedelta


time_interval = timedelta(minutes = 5)
df = now3[[ 'time', 'size', 'price']]


# extract time size for merge
df_time_size= df[['time', 'size']]
df_time_size.loc[:, 'time'] = df_time_size.loc[:, 'time'] + time_interval

# inner join dataframe by size&time
df = df_time_size.merge(df[['time', 'size', 'price']], how = 'inner')
df['orig_time'] = df['time'] - time_interval
df=df.groupby('time').last().reset_index()

df1= df.loc[df["size"] == 4, "price"]
df2= df.loc[df["size"] == 4, "time"]
df3= df.loc[df["size"] == 4, "size"]
df4=df.loc[df["size"] == 4, "orig_time"]
frames = [df3,df1,df2,df4]
result = pd.concat(frames, axis=1, sort=True)
a=pd.merge(result,df10, on="orig_time")
b=a[['size_x' ,'price_x','time','orig_time','price_y']]
b.columns=['size',' price','time','orig_time','orig_price']
print(b)

export_csv =b.to_csv('empty.csv', index = None, header=True)

其中,打印出:

    size   price                time           orig_time  orig_price
0    4.0  9244.5 2019-11-03 04:43:00 2019-11-03 04:38:00      9247.0
1    4.0  9240.5 2019-11-03 05:37:00 2019-11-03 05:32:00      9245.0
2    4.0  9176.5 2019-11-03 07:44:00 2019-11-03 07:39:00      9160.5
3    4.0  9149.5 2019-11-03 08:38:00 2019-11-03 08:33:00      9158.5
4    4.0  9167.0 2019-11-03 08:57:00 2019-11-03 08:52:00      9172.0
5    4.0  9184.0 2019-11-03 09:53:00 2019-11-03 09:48:00      9178.0
6    4.0  9181.0 2019-11-03 09:58:00 2019-11-03 09:53:00      9184.0
7    4.0  9181.0 2019-11-03 09:59:00 2019-11-03 09:54:00      9185.5
8    4.0  9164.5 2019-11-03 10:26:00 2019-11-03 10:21:00      9164.5

我收到以下错误: “试图在DataFrame的切片副本上设置一个值。 尝试使用.loc“

有人可以帮我清理代码/检测到此错误吗?我相信这与最后几行代码有关吗?

1 个答案:

答案 0 :(得分:0)

当您将一个df设置为等于另一个时,例如:

df2 = df

Pandas实际上并未创建新的DataFrame。它只是标志着您每次引用df2时也同时引用了df

因此,当您执行df_time_size= df[['time', 'size']]时,它会使熊猫感到困惑。您实际上是将原始DataFrame的一部分设置为新变量,而不是创建新DataFrame。因此,就像两个DataFrame相同但不同。

如果您真的想要一个新的DataFrame,请执行@Chris建议的操作并添加.copy()

df_time_size= df[['time', 'size']].copy()

或reindex()

df_time_size= df[['time', 'size']].reindex()

第一个将按原样复制,第二个将重置索引。

对于列表和其他python对象,此问题类似,这肯定会造成混淆。对于我自己,即使没有设置切片,我也使用.copy()。它可以帮助我确保我不会意外创建镜像DataFrame / list / dictionary。