我正在尝试更改数据帧中很长的列(约1mio条目)的值。我有类似的东西
####ID_Orig
3452
3452
3452
6543
6543
...
我想要类似的东西
####ID_new
0
0
0
1
1
...
此刻我正在这样做:
j=0
for i in range(0,1199531):
if data.ID_orig[i]==data.ID_orig[i+1]:
data.ID_orig[i] = j
else:
data.ID_orig[i] = j
j=j+1
哪个大约需要时间...有更快的方法吗?
我不知道ID_orig
的值是什么,单个值出现的频率如何。
答案 0 :(得分:1)
使用factorize
,但如果组重复,则将输出值设置为相同的数字。
另一种解决方案是比较ne
(!=
)个shift
的值与cumsum
的解决方案,它更通用-总是创建新值,即使重复组值也是如此:< / p>
df['ID_new1'] = pd.factorize(df['ID_Orig'])[0]
df['ID_new2'] = df['ID_Orig'].ne(df['ID_Orig'].shift()).cumsum() - 1
print (df)
ID_Orig ID_new1 ID_new2
0 3452 0 0
1 3452 0 0
2 3452 0 0
3 6543 1 1
4 6543 1 1
5 100 2 2
6 100 2 2
7 6543 1 3 <-repeating group
8 6543 1 3 <-repeating group
答案 1 :(得分:0)
您可以执行此操作...
import collections
l1 = [3452, 3452, 3452, 6543, 6543]
c = collections.Counter(l1)
l2 = list(c.items())
l3 = []
for i, t in enumerate(l2):
for x in range(t[1]):
l3.append(i)
for x in l3:
print(x)
这是输出:
0
0
0
1
1
答案 2 :(得分:0)
您可以使用以下内容。在以下实现中,原始ID中的重复ID将获得相同的ID。该实现基于从列中删除重复项,并为每个唯一ID分配不同的编号以形成Enw ID。然后将这些新ID合并到原始数据集中
import numpy as np
import pandas as pd
from time import time
num_rows = 119953
input_data = np.random.randint(1199531, size=(num_rows,1))
data = pd.DataFrame(input_data)
data.columns = ["ID_orig"]
data2 = pd.DataFrame(input_data)
data2.columns = ["ID_orig"]
t0 = time()
j=0
for i in range(0,num_rows-1):
if data.ID_orig[i]==data.ID_orig[i+1]:
data.ID_orig[i] = j
else:
data.ID_orig[i] = j
j=j+1
t1 = time()
id_new = data2.loc[:,"ID_orig"].drop_duplicates().reset_index().drop("index", axis=1)
id_new.reset_index(inplace=True)
id_new.columns = ["id_new"] + id_new.columns[1:].values.tolist()
data2 = data2.merge(id_new, on="ID_orig")
t2 = time()
print("Previous: ", round(t1-t0, 2), " seconds")
print("Current : ", round(t2-t1, 2), " seconds")
仅使用11.9万行的上述程序的输出为
Previous: 12.16 seconds
Current : 0.06 seconds
随着行数的增加,运行时差异也会增加更多。
编辑 使用相同的行数:
>>> print("Previous: ", round(t1-t0, 2))
Previous: 11.7
>>> print("Current : ", round(t2-t1, 2))
Current : 0.06
>>> print("jezrael's answer : ", round(t3-t2, 2))
jezrael's answer : 0.02