[英]Replace column values in a large dataframe
我有一个 dataframe 具有类似的 id 和时空数据,如下所示:
car_id lat long
xxx 32 150
xxx 33 160
yyy 20 140
yyy 22 140
zzz 33 70
zzz 33 80
. . .
我想用car_id
, car_id
, car_3, ...应替换为的名称:
u_values = [i for i in df['car_id'].unique()]
r = ['car'+str(i) for i in range(len(u_values))]
现在我不确定如何用列表值替换car_id
列中的所有唯一数字,所以结果是这样的:
car_id lat long
car_1 32 150
car_1 33 160
car_2 20 140
car_2 22 140
car_3 33 70
car_3 33 80
. . .
创建从u_values
到r
和 map 到car_id
列的映射。 还分别使用tolist()
方法和 f-strings 简化了u_values
和r
的定义。
u_values = df['car_id'].unique().tolist()
r = [f'car_{i}' for i in range(len(u_values))]
mapping = pd.Series(r, index=u_values)
df['car_id'] = df['car_id'].map(mapping)
也就是说,向量化字符串连接似乎足以完成这项任务。 factorize()
方法对字符串进行编码。
df['car_id'] = 'car_' + pd.Series(df['car_id'].factorize()[0], dtype='string')
当我对这些方法进行计时(我省略了 Juan Manuel Rivera 的解决方案,因为replace
非常慢,并且代码永远需要更大的数据),基于 OP 代码的map()
实现结果证明是最快的。
factorize()
实现虽然简洁,但毕竟并不快。 我也同意 pasnik 的观点,他们的解决方案是最容易阅读的。
# a dataframe with 500k rows and 100k unique car_ids
df = pd.DataFrame({'car_id': np.random.default_rng().choice(100000, size=500000)})
%timeit u_values = df['car_id'].unique().tolist(); r = [f'car_{i}' for i in range(len(u_values))]; mapping = pd.Series(r, index=u_values); df.assign(car_id=df['car_id'].map(mapping))
# 136 ms ± 2.92 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df.assign(car_id = 'car_' + pd.Series(df['car_id'].factorize()[0], dtype='string'))
# 602 ms ± 19.3 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit r={k:'car_{}'.format(i) for i,k in enumerate(df['car_id'].unique())}; df.assign(car_id=df['car_id'].map(r))
# 196 ms ± 3.02 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
如果您使用字典来维护每个唯一值 (xxxx,yyyy...) 和您想要的新 id (1, 2, 3...) 之间的关系,可能会更容易
newIdDict={}
idCounter=1
for i in df['Car id'].unique():
if i not in newIdDict:
newIdDict[i] = 'car_'+str(idCounter)
idCounter += 1
然后,您可以使用 Pandas 替换 function 来更改 car_id 列中的值:
df['Car id'].replace(newIdDict, inplace=True)
考虑到这将更改 dataframe 中的所有 xxxx,yyyy,因此如果您在 lat 或 long 列中有任何 xxxx,它也会被修改
到目前为止的答案对我来说似乎有点复杂,所以这里有另一个建议。 这将创建一个字典,其中旧名称作为键,新名称作为值。 即可以使用 map 将旧值转换为新值。
r={k:'car_{}'.format(i) for i,k in enumerate(df['car_id'].unique())}
df['car_id'] = df['car_id'].map(r)
编辑:使用 factorize 的答案可能更好,即使我认为这更容易阅读
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.