使用 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 。 iloc
和 loc
可能是语法和用途上最直接的类比,但速度要慢得多。对于 numpy 和 pandas,这是一种相当普遍的情况。 Pandas 比 numpy 做得更多(标记列/索引、自动对齐等),但速度不同程度不同。当您需要速度并且可以在 numpy 中执行操作时,请在 numpy 中执行。
我认为简而言之,这里的权衡是 loc
和 iloc
会更慢,但 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/