【问题标题】:pandas efficient dataframe set rowpandas 高效数据框集行
【发布时间】:2013-09-17 07:03:39
【问题描述】:

首先我预分配了以下空 DataFrame:

df=DataFrame(columns=range(10000),index=range(1000))

然后我想用长度为 10000 的 numpy 数组作为数据逐行(有效地)更新df。我的问题是:我什至不知道应该使用哪种 DataFrame 方法来完成这项任务。

谢谢!

【问题讨论】:

  • 这将非常低效。最好逐列构建框架,然后在最后转置。
  • 如果你已经有了numpy数组作为数据,为什么不把它放到DataFrame构造函数中呢??
  • @AndyHayden,实际上我有一个生成器列表作为某个函数的返回值,一旦我list(),列表中的每个生成器都将是一个 numpy 数组(在框架中提供一行)它。您认为同时list() 他们更有效率吗?
  • 如果你可以用 list 来做(内存方面)它会很有效。如果内存是个问题,另一种选择是用chunkbychunk(即分几块读取并连接结果)。

标签: python pandas dataframe


【解决方案1】:

这里有 3 种方法,只有 100 列,1000 行

In [5]: row = np.random.randn(100)

逐行赋值

In [6]: def method1():
   ...:     df = DataFrame(columns=range(100),index=range(1000))
   ...:     for i in xrange(len(df)):
   ...:         df.iloc[i] = row
   ...:     return df
   ...: 

在列表中构建数组,一次创建所有框架

In [9]: def method2():
   ...:     return DataFrame([ row for i in range(1000) ])
   ...: 

按列赋值(两端有转置)

In [13]: def method3():
   ....:     df = DataFrame(columns=range(100),index=range(1000)).T
   ....:     for i in xrange(1000):
   ....:         df[i] = row
   ....:     return df.T
   ....: 

这些都有相同的输出帧

In [22]: (method2() == method1()).all().all()
Out[22]: True

In [23]: (method2() == method3()).all().all()
Out[23]: True


In [8]: %timeit method1()
1 loops, best of 3: 1.76 s per loop

In [10]: %timeit method2()
1000 loops, best of 3: 7.79 ms per loop

In [14]: %timeit method3()
1 loops, best of 3: 1.33 s per loop

很明显,建立一个列表,然后一次创建所有框架比进行任何形式的分配要快几个数量级。作业涉及复制。一次构建所有内容只复制一次。

【讨论】:

  • 我刚刚尝试过def method4(): df = pd.DataFrame(columns=range(100),index=range(1000)) for i in xrange(len(df)): df.values[i,:]=row return df,它比method2() 快了大约40%。我知道 .values 赋值并不总是类型安全的,但如果你知道你的 df 结构,它应该没问题。对吗?
  • 或者,替换循环并直接分配df.values[:,:] = row,它的工作方式是在分配时逐行重复行,使您的速度进一步提高 2 倍,总体上比 method2() 快 4 倍。对于方法二、四和五,我的每个循环分别为 25.5 毫秒、15.8 毫秒和 5.83 毫秒。
  • 对于这个问题并不重要,但我发现 df1.equals(df2) 比 (df1 == df2).all().all() 更具可读性,只是把它扔给任何人不知道比较数据帧的equals方法
  • .equals() 比这篇文章更新 - 可能是 0.14 或 0.15
【解决方案2】:
df=DataFrame(columns=range(10),index=range(10))
a = np.array( [9,9,9,9,9,9,9,9,9,9] )

更新行:

df.loc[2] = a

使用杰夫的想法...

df2 = DataFrame(data=np.random.randn(10,10), index=arange(10))
df2.head().T

我写了一个笔记本来回答这个问题: https://www.wakari.io/sharing/bundle/hrojas/pandas%20efficient%20dataframe%20set%20row

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-30
    • 2017-08-22
    • 2023-03-04
    • 2014-09-01
    • 2017-10-15
    • 2015-11-24
    • 2012-08-31
    • 1970-01-01
    相关资源
    最近更新 更多