优化Python代码-Pandas/Numpy用法

优化Python代码-Pandas/Numpy用法,python,pandas,numpy,optimization,Python,Pandas,Numpy,Optimization,我有一个python程序需要很长时间才能运行,很可能是因为我使用的是循环,我希望在某个部分中使用Pandas或Numpy可以获得一些帮助,以加快运行速度。第一个FOR循环似乎可以通过pandas或numpy进行一些优化。这就是说,我对熊猫或numpy的复杂性并不十分熟悉,无法实现这个循环。非常感谢您的帮助,如果有任何问题,请告诉我,谢谢 df = data below df2 = pandas.DataFrame() for i in df.index: if df.V[i]&

我有一个python程序需要很长时间才能运行,很可能是因为我使用的是循环,我希望在某个部分中使用Pandas或Numpy可以获得一些帮助,以加快运行速度。第一个FOR循环似乎可以通过pandas或numpy进行一些优化。这就是说,我对熊猫或numpy的复杂性并不十分熟悉,无法实现这个循环。非常感谢您的帮助,如果有任何问题,请告诉我,谢谢

df = data below    
df2 = pandas.DataFrame()

for i in df.index:
    if df.V[i]>1:
        for f in range(0,df.V[i]):
            df2 = df2.append(df.loc[i],ignore_index=True)
    elif df.V[i]==1:
        df2 = df2.append(df.loc[i],ignore_index=True)


df2.V = 1
df2['Grouper']=""


bv=10
y=bv
x=len(df2)


for d in range(0,x,y):
    z = d+y
    df2['Grouper'][d:z]=d


df3 = df2.groupby('Grouper').agg({'Date_Time':'first','L1':'last','H':'max','L2':'min','O':'first'})
df3 = df3.reset_index(drop=True)
df3 = df3[['Date_Time','O','H','L1','L2']]
这是我在本程序(df)中使用的数据示例:


for
循环当然非常慢:首先,在计算时间方面,索引到数据帧的成本相当高。通过
df.V[i]
中的链接索引,还有另一个小的性能损失;如果您改为
df.loc[i,'V']
,事情会稍微快一点。尽管如此,通过索引遍历数据帧的速度非常慢,并且通常可以避免大多数问题(如果必须这样做,
df.iterrows()
提供了一个稍微快一点的迭代器)。代码缓慢的另一个原因是,每次调用
.append()
方法时,您都在创建数据帧的副本,这对于大数据集来说非常麻烦。在这个例子中,我们可以避免几乎所有这些

我猜你有一些时间序列数据是用整数索引的;当数据按时间索引时,pandas可以很好地处理此类问题(重采样),因此我们将强制对数据使用时间格式,并使用
resample
方法

df['v'] = pd.to_datetime(df.V.cumsum()) # assign times to each datapoint; in this case, nanoseconds after the start of Unix time.
r = df.set_index('v').resample('10N') # the 'N' stands for nanoseconds
df3 = r.agg({'Date_Time':'first','L1':'last','H':'max','L2':'min','O':'first'})
df3.interpolate(method = 'zero', inplace = True)
df3.reset_index(drop = True, inplace = True)
to_fix = df3.index[df3.Date_Time.isnull()]
for i in to_fix:
    df3.loc[i,'Date_Time'] = df3.loc[i-1,'Date_Time']
一些评论:

  • 当有较大的V时,需要使用插值方法 “交叉”聚合期;参数
    method='zero'
    告诉我们 熊猫们只能坐在它前面的那一排。但是,它不起作用 对于字符串,因此需要手动替换它们;最好的我 可以想到的是一个
    for
    循环,希望它不会重复太多次
  • inplace=True
    参数表示直接修改数据,而不是创建数据帧的修改副本并用其替换旧副本
  • .agg()
    方法允许您对要聚合的对象使用多个函数,因此如果您想使用
    L
    'min'
    'last'
    ,可以传递参数
    {'L':['min','last']}
    {'L':{'custom colname1':'min','custom colname2:'min'}
    。结果是,这会生成一个嵌套的列索引,其中最简单的展平方法是直接修改数据帧的
    .columns
    属性(但要注意名称的顺序,因为传递到
    .agg()
    方法的字典没有顺序

  • for
    循环当然非常慢:首先,在计算时间方面,索引到数据帧的成本相当高。在
    df.V[i]
    中通过链式索引还有另一个小的性能损失;如果执行
    df.loc[i,'V']
    相反。尽管如此,通过索引遍历数据帧的速度非常慢,并且通常可以避免大多数问题(如果必须这样做,
    df.iterrows()
    提供了一个稍微快一点的迭代器)。代码缓慢的另一个原因是,每次调用
    .append()
    方法时,您都在创建数据帧的副本,这对于大数据集来说非常麻烦。在本例中,我们可以避免执行几乎所有这些操作

    我想你有一些时间序列数据是用整数索引的;当你有时间索引的数据时,pandas可以很好地处理这类问题(重采样),所以我们将对数据强制使用时间格式,并使用
    重采样
    方法

    df['v'] = pd.to_datetime(df.V.cumsum()) # assign times to each datapoint; in this case, nanoseconds after the start of Unix time.
    r = df.set_index('v').resample('10N') # the 'N' stands for nanoseconds
    df3 = r.agg({'Date_Time':'first','L1':'last','H':'max','L2':'min','O':'first'})
    df3.interpolate(method = 'zero', inplace = True)
    df3.reset_index(drop = True, inplace = True)
    to_fix = df3.index[df3.Date_Time.isnull()]
    for i in to_fix:
        df3.loc[i,'Date_Time'] = df3.loc[i-1,'Date_Time']
    
    一些评论:

  • 当有较大的V时,需要使用插值方法 “交叉”聚合周期;参数
    method='zero'
    说明 熊猫们只能坐在它前面的那一排。但是,它不起作用 对于字符串,因此需要手动替换它们;最好的 可以想到的是一个
    for
    循环,希望它不会重复太多次
  • inplace=True
    参数表示直接修改数据,而不是创建数据帧的修改副本并用其替换旧副本
  • .agg()
    方法允许您对要聚合的对象使用多个函数,因此如果您想使用
    L
    'min'
    'last'
    ,可以传递参数
    {'L':['min','last']}
    {'L':{'custom colname1':'min','custom colname2:'min'}
    。结果是,这会生成一个嵌套的列索引,其中最简单的展平方法是直接修改数据帧的
    .columns
    属性(但要注意名称的顺序,因为传入
    .agg()的字典没有顺序

  • 您可以包含原始数据和预期数据吗?给定的数据框不起作用,因为有两个同名列(您应该不惜一切代价避免这一点)会导致groupby崩溃)。如果您用文字解释您试图实现的目标,也会很有帮助,因为可能会尝试不同的方法。@KenWei我应用了您建议的更改。目的是按“V”列细分数据,因此df中的第2行在df2中将有27个相同数据项。然后,我将df2中的数据重新组合到crea中基于列“V”中的一组条目的te Bucket。基本上是尝试创建常量条。是否可以包含原始数据和预期数据?给定的数据帧将不起作用,因为具有两个同名列(您应该不惜一切代价避免)会导致groupby崩溃)。如果你能解释一下你的想法也会很有帮助