Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何快速对多个数据帧进行子集划分?_Python_Pandas_Dataframe_Numpy - Fatal编程技术网

Python 如何快速对多个数据帧进行子集划分?

Python 如何快速对多个数据帧进行子集划分?,python,pandas,dataframe,numpy,Python,Pandas,Dataframe,Numpy,我有180个DataFrame对象,每个对象有3130行,内存大约为300KB。 该索引是一个日期时间索引,从2000-01-03到2011-12-31的工作日: from datetime import datetime import pandas as pd freq = pd.tseries.offsets.BDay() index = pd.date_range(datetime(2000,1,3), datetime(2011,12,31), freq=freq) df = pd.

我有180个
DataFrame
对象,每个对象有3130行,内存大约为300KB。 该索引是一个日期时间索引,从2000-01-03到2011-12-31的工作日:

from datetime import datetime
import pandas as pd
freq = pd.tseries.offsets.BDay()

index = pd.date_range(datetime(2000,1,3), datetime(2011,12,31), freq=freq)

df = pd.DataFrame(index=index)
df['A'] = 1000.0
df['B'] = 2000.0
df['C'] = 3000.0
df['D'] = 4000.0
df['E'] = 5000.0
df['F'] = True
df['G'] = 1.0
df['H'] = 100.0
我利用numpy/pandas矢量化对所有数据进行预处理,然后每天循环遍历数据帧。为了防止“前瞻性偏差”的可能性并从未来获取数据,我必须确保每天只返回数据帧的一个子集,直到该数据点。我解释:如果我正在处理的当前数据点是
datetime(2010,5,15)
我需要
datetime(2000,1,3)
datetime(2010,5,15)
的数据。您不能访问比
datetime(2010,5,15)
最近的数据。使用这个子集,我将进行其他无法矢量化的计算,因为它们依赖于路径

我修改了我的原始循环,如下所示:

def get_data(datapoint):
    return df.loc[:datapoint]
    
calendar = df.index

for datapoint in calendar:
    x = get_data(datapoint)   
这种代码非常慢。提高速度的最佳选择是什么? 如果我不尝试防止前瞻性偏差,我的生产代码运行大约需要3分钟,但风险太大。像这样的代码需要13分钟,这是不可接受的

%%timeit

一个稍微快一点的选项是使用
iloc
而不是
loc
,但它仍然很慢:

def get_data2(datapoint):
    idx = df.index.get_loc(datapoint)
    return df.iloc[:idx]

for datapoint in calendar:
    x = get_data(datapoint)  
每个回路371 ms±23.2 ms(7次运行的平均值±标准偏差,每个回路1次)

每个回路327 ms±7.05 ms(7次运行的平均值±标准偏差,每个回路1次)

原始代码并不试图防止前瞻性偏差的可能性,当为每个数据点调用时,它只返回整个
DataFrame
。在本例中,实际代码快100倍,实际代码快4倍

def get_data_no_check():
    return df

for datapoint in calendar:
    x = get_data_no_check() 

每个循环2.87 ms±89.8µs(7次运行的平均值±标准偏差,每个循环100次)

看看这是否适用于您:

datapoint_range = pd.date_range(datetime(2000,1,3), datetime.now(), freq=freq)
datapoint = datapoint_range[-1]
逻辑是:将结束日期替换为今天,以确保不是将来的日期。然后获取范围的最后日期


然后使用你的
df.loc[:datapoint]
来获得你想要的范围。

我这样解决它:首先我预处理
数据框中的所有数据,以利用pandas矢量化,然后我将其转换为
dict of dict
并对其进行迭代,防止出现“前瞻性偏差”。由于数据已经过预处理,我可以避免
DataFrame
开销。生产代码处理速度的提高让我哑口无言:从30多分钟下降到40秒

# Convert the DataFrame into a dict of dict

for s, data in self._data.items():
    self._data[s] = data.to_dict(orient='index')

如果您有预设的数据点值,为什么不直接使用
df.loc[:datapoint]
?为什么必须循环遍历数据帧的所有索引?循环遍历所有索引,每次指向该索引时,这实际上不是对任何内容进行子集划分。这有用吗?这是在3分钟内运行的代码所做的,但它是有风险的。你可能会很累,为datapoint输入了错误的值,你将从未来获取数据,这就是我试图避免的,你不能先对日期进行排序,以确保当前日期之后的日期都在当前日期之后吗
df.sort_值(按class='date',升序=True)
索引已被排序我认为您可以设计出一种方法来计算日期,只需将其称为datapoint,它是一个工作日,并验证为过去或现在的日期,而不是将来的日期。然后只需使用df切片来获得所需的日期范围。在我的示例中,结束日期是2011-12-31。使用datetime.now()已经是“未来”。。。
# Convert the DataFrame into a dict of dict

for s, data in self._data.items():
    self._data[s] = data.to_dict(orient='index')