Python: Как изменить те же числа в серии / столбце на другие значения? - PullRequest
0 голосов
/ 29 ноября 2018

Я пытаюсь изменить значения очень длинного столбца (около 1 миллиона записей) во фрейме данных.У меня есть что-то вроде

####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 голосов
/ 29 ноября 2018

Используйте factorize, но если дублирующиеся группы, то выходные значения устанавливаются на одно и то же число.

Другое решение со сравнением по ne (!=) из shift ed значений с cumsum является более общим - всегда создавать новые значения, даже если повторяются групповые значения:

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
0 голосов
/ 29 ноября 2018

Вы можете использовать следующее.В следующей реализации дубликаты идентификаторов в исходном идентификаторе получат те же идентификаторы.Реализация основана на удалении дубликатов из столбца и назначении различного номера каждому уникальному идентификатору для формирования идентификаторов enw.Эти новые идентификаторы затем объединяются в исходный набор данных

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")

. Вывод программы, использующей только 119 тыс. Строк, составляет

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
0 голосов
/ 29 ноября 2018

Вы можете сделать это ...

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...