python - 有效地写入 Pandas 中的多个相邻列

标签 python numpy pandas

使用 numpy ndarray 可以一次写入多个列而无需先制作副本(只要它们相邻)。如果我想写入数组的前三列,我会写

a[0,0:3] = 1,2,3 # this is very fast ('a' is a numpy ndarray)

我希望在 pandas 中我同样能够像这样通过“标签切片”选择多个相邻的列(假设前 3 列标记为“a”、“b”、“c”)

a.loc[0,'a':'c'] = 1,2,3 # this works but is very slow ('a' is a pandas DataFrame)

或类似的

a.iloc[0,3:6] = 1,2,3 # this is equally as slow

但是,与写入仅需几微秒的 numpy 数组相比,这需要数百毫秒。我不清楚 pandas 是否在幕后制作数组的副本。我能找到的以这种方式写入数据帧的唯一方法是直接在底层 ndarray 上工作

a.values[0,0:3] = 1,2,3 # this works fine and is fast

我是否遗漏了 Pandas 文档中的某些内容,或者他们无法以与 numpy 相当的速度对 Pandas 数据帧进行多个相邻列索引?

编辑

这是我正在使用的实际数据框。

>> conn = sqlite3.connect('prath.sqlite')
>> prath = pd.read_sql("select image_id,pixel_index,skin,r,g,b from pixels",conn)
>> prath.shape
(5913307, 6)
>> prath.head()
   image_id  pixel_index  skin    r    g    b
0        21       113764     0    0    0    0
1        13       187789     0  183  149  173
2        17       535758     0  147   32   35
3        31         6255     0  116    1   16
4        15       119272     0  238  229  224
>> prath.dtypes
image_id       int64
pixel_index    int64
skin           int64
r              int64
g              int64
b              int64
dtype: object

这里是不同索引方法的一些运行时比较(同样,pandas 索引非常慢)

>> %timeit prath.loc[0,'r':'b'] = 4,5,6
1 loops, best of 3: 888 ms per loop
>> %timeit prath.iloc[0,3:6] = 4,5,6
1 loops, best of 3: 894 ms per loop
>> %timeit prath.values[0,3:6] = 4,5,6
100000 loops, best of 3: 4.8 µs per loop

最佳答案

编辑澄清:我不认为 pandas 在速度和语法方面可以直接模拟在 numpy 中设置 View 。 ilocloc 可能是语法和用途上最直接的类比,但速度要慢得多。对于 numpy 和 pandas,这是一种相当普遍的情况。 Pandas 比 numpy 做得更多(标记列/索引、自动对齐等),但速度不同程度不同。当您需要速度并且可以在 numpy 中执行操作时,请在 numpy 中执行。


我认为简而言之,这里的权衡是 lociloc 会更慢,但 100% 的时间都可以工作,而 values会很快,但并不总是有效(老实说,我什至没有意识到它会以你让它工作的方式工作)。

但这是一个非常简单的示例,其中 values 不起作用,因为列“g”是 float 而不是整数。

prath['g'] = 3.33

prath.values[0,3:6] = 4,5,6

prath.head(3)

   image_id  pixel_index  skin    r     g    b
0        21       113764     0    0  3.33    0
1        13       187789     0  183  3.33  173
2        17       535758     0  147  3.33   35

prath.iloc[0,3:6] = 4,5,6

prath.head(3)

   image_id  pixel_index  skin    r     g    b
0        21       113764     0    4  5.00    6
1        13       187789     0  183  3.33  173
2        17       535758     0  147  3.33   35

当列是同类类型时,您通常可以从 pandas 获得类似 numpy 的速度和行为,您要小心这一点。 编辑添加:正如@toes 在评论中指出的那样,文档确实说明您可以使用同类数据执行此操作。但是,如上例所示,它可能非常容易出错,而且我认为很多人不会认为这是 pandas 中的良好通用做法。

我的一般建议是,如果您需要速度(并且具有同类数据类型),则在 numpy 中执行操作,而在不需要时,则使用 pandas。好消息是 numpy 和 pandas 一起玩得很好,所以在数据帧和数组之间转换真的不难。

编辑以添加: 即使将“g”列作为 float ,以下内容似乎也有效(尽管有警告)。速度介于values方式和loc/iloc方式之间。我不确定这是否可以一直有效。只是把它作为一种可能的中间方法。

prath[0:1][['r','g','b']] = 4,5,6

关于python - 有效地写入 Pandas 中的多个相邻列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31132784/

相关文章:

python - `pipenv install --index` 和 `pipenv install --pypi-mirror` 有什么区别?

python - 在 Python 中测试抽象类

python - 基于 Pandas 中特殊字符分隔列中的每个项目进行聚合

python - 如何使用python将RGB多波段GeoTIFF投影到指定区域范围?

python - Go 与 Python 的 crypt.crypt 等价的是什么?

python - arr = [a,b] 选择 a, x% 的时间

python - 使用 numpy.genfromtxt 读取单行 CSV

python - 如何更改numpy数组中的像素值

python - 从两个数据框创建新的数据框。一个 df 包含列索引,另一个 df 包含值

python - 在 Pandas 数据框中成对计数