У меня есть фреймворк списков, похожий на приведенный ниже (рис. а). Существует один ключевой столбец, за которым следуют столбцы combined
. Пример желаемого результата показан ниже на рисунке B.
Я пробовал некоторые методы с iteritems(), но эти кадры данных могут иметь длину от сотен тысяч до миллионов строк, что делает его невероятно медленным. Поэтому я стараюсь избегать решений, которые используют это.
Я хотел бы использовать что-то вроде понимания списка, показанного в этот ТАК пост, но мне не удалось заставить его работать с пандами.
# example data
data = {'key': ['1_1', '1_2', '1_3'],
'valueA': [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]],
'valueB': [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]],
'valueN': [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]]}
dataSet = pd.DataFrame(data)
Рисунок А
Рисунок Б
Обновлено: я очень ценю все ответы, которые я получил до сих пор! В настоящее время я просматриваю и синхронизирую каждый в своем полноразмерном наборе данных, чтобы понять, какой из них будет работать лучше всего в этом случае. Я обновлю с моим результатом в ближайшее время!
Редактировать 2: я протестировал основные решения, представленные здесь, на нескольких моих больших наборах данных, и их среднее время ниже.
# Lambda/Apply a nested list comprehension
shakiba.mrd: 1.12 s
# Sum columns
jfaccioni: 2.21 s
# Nested list comprehension with iterrows
mozway: 0.95 s
# Adding column lists together
politinsa: 3.50 s
Еще раз спасибо всем за их вклад!
Вы можете добавлять списки в python
df['combined'] = df['valueA'] + df['valueB'] + df['valueN']
Или для нескольких столбцов:
df['combined'] = [[] for _ in range(len(df))]
for letter in ['A', 'B', 'C', ...., 'N']:
df['combined'] += df[f'value{letter}']
Это может выглядеть как хорошее решение, но многократное добавление списка имеет квадратичную сложность, и поэтому его действительно следует избегать.
@mozway да, но мой ответ здесь не проблема, это их вопрос. Если он хочет объединить несколько списков (это был их вопрос), он может использовать мое решение. Настоящая проблема заключается в том, почему они должны объединять списки в первую очередь, и является ли этот шаг критичным по времени.
Сначала вы должны объединить эти столбцы в один новый столбец:
merge_columns = list(dataSet.columns)
merge_columns.remove("key")
dataSet["combined"] = dataSet[merge_columns].values.tolist()
Затем вы должны составить список из списка списков в каждой строке:
dataSet["combined"] = dataSet["combined"].apply(lambda x: [item for sublist in x for item in sublist])
Вы можете просто выбрать столбцы, содержащие списки, а затем суммировать столбцы с помощью .sum(axis=1)
.
Это работает следующим образом:
import pandas as pd
data = {
'key': ['1_1', '1_2', '1_3'],
'valueA': [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]],
'valueB': [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]],
'valueN': [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]],
}
dataSet = pd.DataFrame(data)
columns_to_combine = ['valueA', 'valueB', 'valueN']
dataSet['combined'] = dataSet[columns_to_combine].sum(axis=1)
dataSet.drop(columns=columns_to_combine, inplace=True) # remove the old columns
print(dataSet)
# output:
# key combined
# 0 1_1 [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
# 1 1_2 [7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12]
# 2 1_3 [13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18]
sum
в списках имеет квадратичную сложность, поскольку он снова строит новый список для каждого добавленного элемента.
Это самый простой способ достичь своей цели.
dataSet['Lists'] = dataSet['valueA'] + dataSet['valueB'] + dataSet['valueN'] dataSet.drop(columns=['valueA','valueB',"valueN"],inplace=True) print(dataSet)
Вы можете использовать понимание вложенного списка:
dataSet['combined'] = [[e for l in x for e in l]
for _,x in dataSet.filter(like='value').iterrows()]
Выход:
key valueA valueB valueN combined
0 1_1 [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
1 1_2 [7, 8, 9, 10, 11, 12] [7, 8, 9, 10, 11, 12] [7, 8, 9, 10, 11, 12] [7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12, 7, 8, 9, 10, 11, 12]
2 1_3 [13, 14, 15, 16, 17, 18] [13, 14, 15, 16, 17, 18] [13, 14, 15, 16, 17, 18] [13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18, 13, 14, 15, 16, 17, 18]
Сравнение времени с повторным добавлением (100 строк, 100 столбцов, 1000 элементов в списке):
# repeated addition of the lists
8.66 s ± 309 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# nested list comprehension
729 ms ± 285 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
При работе со списками в pandas у вас нет выбора, кроме как зацикливаться (явно или неявно)