Преобразование списков в DataFrame с использованием логики на основе имени списка - PullRequest
1 голос
/ 29 октября 2019

Я пытаюсь построить кадр данных из следующих списков:

A = ['item 1', 'item 2', 'item 3', 'item 4', 'item 5']

B = ['item 2','item 4']

C = ['item 1', 'item 5']

Я хочу, чтобы имя списка (или некоторое представление этого имени) соответствовало значению, как таковому:

dA = [{'item':x, 'A':True} for x in A]
dB = [{'item':x, 'B':True} for x in B]
dC = [{'item':x, 'C':True} for x in C]

В настоящее время я строю свой фрейм данных, используя некоторые уродливые методы. Я хотел бы найти решение для лучших практик здесь:

dfA = pd.DataFrame.from_records(dA)
dfB = pd.DataFrame.from_records(dB)
dfC = pd.DataFrame.from_records(dC)

df = pd.merge(dfA,dfB, 'outer').merge(dfC,'outer').fillna(False)

# Result:
    item    A   B   C
0   item 1  True    False   True
1   item 2  True    True    False
2   item 3  True    False   False
3   item 4  True    True    False
4   item 5  True    False   True

Ответы [ 3 ]

2 голосов
/ 29 октября 2019

Другой способ сделать это без слияния

import pandas as pd

# list all unique items (in case there are not all present in A)
all_items = list(set(A+ B+C))
# create a dataframe with only item column
df = pd.DataFrame({'item':all_items})
# add boolean columns
df['A'] = df['item'].isin(A)
df['B'] = df['item'].isin(B)
df['C'] = df['item'].isin(C)

#   item    A   B   C
#0  item 4  True    True    False
#1  item 3  True    False   False
#2  item 2  True    True    False
#3  item 1  True    False   True
#4  item 5  True    False   True

Если вы хотите что-то красивее или у вас есть больше столбцов для создания, вы также можете использовать словарь

dict_list = {'A': A, 'B': B, 'C':C}
for col in dict_list.keys():
  df[col] = df['item'].isin(dict_list[col])
1 голос
/ 29 октября 2019

Попробуйте pd.crosstab

arr = np.concatenate([A, B, C])
col_arr = np.repeat(['A', 'B', 'C'], [len(A), len(B), len(C)])
pd.crosstab(index=arr, columns=col_arr)

Out[106]:
col_0   A  B  C
row_0
item 1  1  0  1
item 2  1  1  0
item 3  1  0  0
item 4  1  1  0
item 5  1  0  1

Если вы хотите True/False, просто добавьте еще eq(1)

pd.crosstab(index=arr, columns=col_arr).eq(1)

Out[108]:
col_0      A      B      C
row_0
item 1  True  False   True
item 2  True   True  False
item 3  True  False  False
item 4  True   True  False
item 5  True  False   True
1 голос
/ 29 октября 2019

Вы можете использовать pandas.get_dummies :

import pandas as pd

A = ['item 1', 'item 2', 'item 3', 'item 4', 'item 5']
B = ['item 2', 'item 4']
C = ['item 1', 'item 5']

# generate series
s = pd.Series({'A': A, 'B': B, 'C': C})

# apply get dummies and transform
result = pd.get_dummies(s.apply(pd.Series).stack()).sum(level=0).T

print(result)

Выход

        A  B  C
item 1  1  0  1
item 2  1  1  0
item 3  1  0  0
item 4  1  1  0
item 5  1  0  1

Если вы должны иметь логические значения, вы можете сделатьвместо:

result = pd.get_dummies(s.apply(pd.Series).stack()).sum(level=0).T.astype(bool)
...