Добавить несколько строк И один столбец в Dataframe на основе существующего столбца - PullRequest
0 голосов
/ 11 февраля 2019

Я хочу добавить новые строки и добавить новый столбец на основе существующего столбца.Например, допустим, у меня есть следующий Dataframe:

   A          B
   1          a
   2          b
   3          c
   4          b

И словарь с уникальными значениями столбца B в качестве ключей.Каждый ключ связан со списком значений.Эти значения используются для новых строк и столбцов: {a: [x, y, z], b: [x, w, r], c: [x, q]}

Преобразование должно привести к следующему кадру данных:

   A          C          
   1          x
   1          y
   1          z
   2          x
   2          w
   2          r
   3          x
   3          q
   4          x
   4          w
   4          r

Я знаю, как добавить новый столбец, но язастрял с попыткой репликации строк.Какое наиболее эффективное решение этой проблемы?Обновлять ли существующий Dataframe или создавать новый?

Update

Операция будет использоваться на большом кадре данных (20 миллионов + строк) с использованием Dask.

Ответы [ 4 ]

0 голосов
/ 11 февраля 2019

Еще один метод с использованием sum() и map():

d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}
df_new= pd.DataFrame({'A': np.repeat(df.A,df.B.map(d).apply(len)).\
              reset_index(drop=True),'B':df.B.map(d).sum()})

Или еще лучше с использованием оператора Reduce (для больших кадров данных) :

import functools,operator
df_new= pd.DataFrame({'A': np.repeat(df.A,df.B.map(d).apply(len)).\
                  reset_index(drop=True),'B':functools.reduce(operator.iadd, df.B.map(d),[])})
print(df_new)

    A  B
0   1  x
1   1  y
2   1  z
3   2  x
4   2  w
5   2  r
6   3  x
7   3  q
8   4  x
9   4  w
10  4  r
0 голосов
/ 11 февраля 2019

Мой ответ - создание нового DF.

di = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}
x = df.to_dict()
temp = list(zip(df.A, [di[z] for z in x['B'].values()]))
A = [[x[0]] * len(x[1]) for x in temp]
B = [x[1] for x in temp]

A = [item for sublist in A for item in sublist]
B = [item for sublist in B for item in sublist]

pd.DataFrame({'A':A, 'B':B})
0 голосов
/ 11 февраля 2019

Вы можете преобразовать dict в DataFrame со столбцами с именами B и C

df2 = pd.DataFrame.from_dict(d, orient='index').stack().reset_index().iloc[:, [0, -1]]
df2.columns = ['B', 'C']

, объединить этот новый df2 с вашим начальным df и выбрать данные, которые вы хотите иметь:

df.merge(df2, on='B').set_index('A')['C'].sort_index()
0 голосов
/ 11 февраля 2019

Я предлагаю создать новое с map, np.repeat и chain.from_iterable:

d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}

s = df['B'].map(d)
lens = [len(x) for x in s]

from itertools import chain

df = pd.DataFrame({
    'A' : df['A'].values.repeat(lens),
    'C' : list(chain.from_iterable(s.values.tolist()))
})
print (df)
    A  C
0   1  x
1   1  y
2   1  z
3   2  x
4   2  w
5   2  r
6   3  x
7   3  q
8   4  x
9   4  w
10  4  r

Более общее решение работает, если какое-то значение словаря не совпадает:

Возвращение первого решенияошибка, потому что map возвращает отсутствующее значение:

TypeError: объект типа 'NoneType' не имеет len ()

print (df)
   A  B
0  1  d <- change data
1  2  b
2  3  c
3  4  b

d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}

s = [d.get(x, [x]) for x in df['B']]
print (s)
[['d'], ['x', 'w', 'r'], ['x', 'q'], ['x', 'w', 'r']]

lens = [len(x) for x in s]

from itertools import chain

df = pd.DataFrame({
    'A' : df['A'].values.repeat(lens),
    'B' : list(chain.from_iterable(s))
})
print (df)
   A  B
0  1  d
1  2  x
2  2  w
3  2  r
4  3  x
5  3  q
6  4  x
7  4  w
8  4  r

Поскольку используется dask,другое решение должно быть:

d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}
df1 = pd.DataFrame([(k, y) for k, v in d.items() for y in v], columns=['B','C'])
print (df1)
   B  C
0  a  x
1  a  y
2  a  z
3  b  x
4  b  w
5  b  r
6  c  x
7  c  q

df = df.merge(df1, on='B', how='left')
print (df)
    A  B  C
0   1  a  x
1   1  a  y
2   1  a  z
3   2  b  x
4   2  b  w
5   2  b  r
6   3  c  x
7   3  c  q
8   4  b  x
9   4  b  w
10  4  b  r
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...