Панды добавляют новый столбец и заполняют его элементом из списка, если кортеж двух других столбцов уникален - PullRequest
0 голосов
/ 23 сентября 2018

В настоящее время я пытаюсь добавить некоторые значения списка в новый столбец в моей таблице панд.Первое значение col3 является первым в списке.Второе значение одинаково в случае, если кортеж col1 и col2 остается тем же.Условием для начала добавления следующего элемента списка является то, что это новая уникальная комбинация элементов из столбцов col1 и col2.

Пример:

df = pd.DataFrame({'col1':[1,1,1,1,3,3,3,10], 'col2':[1,1,2,2,9,9,9,5]})

list1=[5,9,3,12]
col1 col2                     col1 col2 col3
1     1                       1     1    5 
1     1                       1     1    5
1     2       should become   1     2    9
1     2  ------------------>  1     2    9
3     9                       3     9    3
3     9                       3     9    3
3     9                       3     9    3
10    5                       10    5    12

Я работал с одним столбцом как условие:

di =dict(zip(df['col1'].unique(),list1))
df['col2'] = df_averageInPanda['col1'].map(di)

Чтобы запустить его с условием кортежа, которое я пробовал drop_duplicate(), поскольку функция unique() не работает с несколькими столбцами, но она не работает, но дает пустое значение col3

di =dict(zip(df[['col1','col2']].drop_duplicates(),list1))
df['col3'] = df['col1'].map(di)

Есть идеи, как это исправить?

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Вот альтернативный метод.Вы можете использовать Pandas для создания нового фрейма данных с уникальными строками (поддержание порядка) и назначения нового столбца.Затем объедините это с вашим исходным фреймом данных:

res = df.merge(df.drop_duplicates().assign(col3=list1))

print(res)

   col1  col2  col3
0     1     1     5
1     1     1     5
2     1     2     9
3     1     2     9
4     3     9     3
5     3     9     3
6     3     9     3
7    10     5    12
0 голосов
/ 23 сентября 2018

Вы можете использовать shift() и сравнить с начальными значениями, чтобы проанализировать, когда значения изменятся, а затем map в ваши значения list1.

s = df.ne(df.shift()).sum(1).cumsum()
df['col3'] = s.map(dict(zip(s.unique(), list1)))

    col1    col2    col3
0   1       1       5
1   1       1       5
2   1       2       9
3   1       2       9
4   3       9       3
5   3       9       3
6   3       9       3
7   10      5       12

Время для малых значений:

df = pd.concat([df]*100).reset_index(drop=True)

%timeit s = df.ne(df.shift()).sum(1).cumsum(); df['col3'] = s.map(dict(zip(s.unique(), list1)))
2.81 ms ± 38.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df.merge(df.drop_duplicates().assign(col3=list1))
3.39 ms ± 32.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Время для больших значений:

df = pd.concat([df]*100000).reset_index(drop=True)

%timeit s = df.ne(df.shift()).sum(1).cumsum(); df['col3_'] = s.map(dict(zip(s.unique(), list1)))
184 ms ± 1.88 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.merge(df.drop_duplicates().assign(col3=list1))
87.6 ms ± 2.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Вподробно, df.ne(df.shift()).sum(1).cumsum() возвращает ряд значений, которые кумулятивно уникальны

0    2
1    2
2    3
3    3
4    5
5    5
6    5
7    7

Затем вы map вводите эти значения в значения list1 и присваиваете их обратно в виде столбца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...