python – 更改数据框中多个loc的最快方法

我有一个包含100万行的pandas数据帧.我想用另一组值替换列中900,000行的值.有没有for循环(我需要两天才能完成)的快速方法吗?

例如,查看此示例数据框,其中我已将100万行压缩为8行

import numpy as np
import pandas as pd

df = pd.DataFrame()
df['a'] = [-1,-3,-4,4,5,6]
df['b'] = [23,45,67,89,-1,2,3]

L2 = [-1,-4]
L5 = [9,10,11]

我希望在没有for循环的情况下,在单次拍摄中替换a为-1,-4的值,或者尽可能快地替换.

关键部分是L5中的值必须根据需要重复.

我试过了

df.loc[df.a < 0,'a'] = L5

但这只适用于len(df.a.values)== len(L5)

解决方法

通过zip从两个列表创建的字典使用 map,最后在 fillna之前替换为原始的非匹配值:

d = dict(zip(L2,L5))
print (d)
{-1: 9,-3: 10,-4: 11}

df['a'] = df['a'].map(d).fillna(df['a'])
print (df)
      a   b
0   9.0  23
1  10.0  45
2  11.0  67
3  11.0  89
4  10.0   0
5   4.0  -1
6   5.0   2
7   6.0   3

性能

它取决于替换列表长度的值的数量

列表长度为100:

np.random.seed(123)
N = 1000000

df = pd.DataFrame({'a':np.random.randint(1000,size=N)})

L2 = np.arange(100)
L5 = np.arange(100) + 10


In [336]: %timeit df['d'] = np.select([df['a'] == i for i in L2],L5,df['a'])
180 ms ± 1.07 ms per loop (mean ± std. dev. of 7 runs,10 loops each)

In [337]: %timeit df['a'].map(dict(zip(L2,L5))).fillna(df['a'])
56.9 ms ± 2.55 ms per loop (mean ± std. dev. of 7 runs,10 loops each)

如果列表长度很小(例如3):

np.random.seed(123)
N = 1000000

df = pd.DataFrame({'a':np.random.randint(100,size=N)})

L2 = np.arange(3)
L5 = np.arange(3) + 10

In [339]: %timeit df['d'] = np.select([df['a'] == i for i in L2],df['a'])
11.9 ms ± 40.6 µs per loop (mean ± std. dev. of 7 runs,100 loops each)

In [340]: %timeit df['a'].map(dict(zip(L2,L5))).fillna(df['a'])
54 ms ± 215 µs per loop (mean ± std. dev. of 7 runs,10 loops each)

相关文章

功能概要:(目前已实现功能)公共展示部分:1.网站首页展示...
大体上把Python中的数据类型分为如下几类: Number(数字) ...
开发之前第一步,就是构造整个的项目结构。这就好比作一幅画...
源码编译方式安装Apache首先下载Apache源码压缩包,地址为ht...
前面说完了此项目的创建及数据模型设计的过程。如果未看过,...
python中常用的写爬虫的库有urllib2、requests,对于大多数比...