Python:如何将“系列/列”中的相同数字更改为其他值?

时间:2018-11-29 07:50:14

标签: python pandas

我正在尝试更改数据帧中很长的列(约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的值是什么,单个值出现的频率如何。

3 个答案:

答案 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