繁体   English   中英

替换大 dataframe 中的列值

[英]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_valuesr和 map 到car_id列的映射。 还分别使用tolist()方法和 f-strings 简化了u_valuesr的定义。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM