У меня есть 2 панды dfs (df1 и df2), как показано здесь:
df1 | столбец1 | столбец2 | столбец3 | столбец4 | столбец5 |
---|---|---|---|---|---|
ряд1 | Собака | Кот | Птица | Дерево | Лев |
ряд2 | Кот | Дракон | Птица | Собака | Дерево |
строка3 | Кот | Собака | Птица | Дерево | Гиппопотам |
ряд4 | Кот | Дерево | Птица | Муравей | Рыбы |
ряд5 | Кот | Дерево | Обезьяна | Дракон | Муравей |
дф2 | столбец1 | столбец2 | столбец3 | столбец4 | столбец5 |
---|---|---|---|---|---|
ряд1 | 3.219843 | 1.3631996 | 1.0051135 | 0,89303696 | 0,4313375 |
ряд2 | 2.8661892 | 1.4396228 | 0,7863044 | 0,539315 | 0,48167187 |
строка3 | 2,5679462 | 1.3657334 | 0,9470184 | 0,79186934 | 0,48637152 |
ряд4 | 3.631389 | 0,94815284 | 0,7561722 | 0,6743943 | 0,5441728 |
ряд5 | 2.4727197 | 1.5941181 | 1.4069512 | 1.064051 | 0,48297918 |
Строковые элементы df1 соответствуют значениям df2. Для обоих фреймов данных существует условие, что элемент (или значение) не повторяется в одной и той же строке. Но можно повторить на разных рядах.
Например, собака строки 1 = 3,219843, птица строки 3 = 0,9470184, птица строки 4 = 0,7561722 и т. д.
Я хотел бы извлечь значения для всех уникальные элементы 1-го df в разные массивы. Нравиться:
Собака = [3,219843, 0,539315, 1,3657334]
Кот = [1,3631996, 2,8661892, 2,5679462, 3,631389, 2,4727197]
и т.д...
Любые идеи?
Большое спасибо!
Можете ли вы предоставить конструкторы данных для входных данных?
@Arkadiusz, это имена df, первый столбец / 1-я строка - это место, где начинаются числа
@mozway К сожалению, я не могу по соображениям конфиденциальности :(
@Steven Я имел в виду ваши примеры… текущий формат неоднозначен с точки зрения столбцов/индексов и т. д.
Предполагая, что ваши первые столбцы df1
и df2
являются индексами соответствующих им df
, мы можем извлечь значения для каждого уникального животного в df1
, используя первый df
в качестве маски для извлечения всех нужных значений из второго (результатом является новый df
с NaN
в нерелевантных ячейках, которые можно превратить в одномерный массив с .stack().values
).
Прежде всего, создайте несколько тестовых данных. Пожалуйста, предоставьте его в такой форме в будущих сообщениях. Об этом говорил @mozway в комментариях. Это высоко ценится.
(Не всегда бывает так, что кто-то готов выполнить все операции копирования и вставки, необходимые для запуска фреймов данных для тестирования.)
import pandas as pd
import numpy as np
index = ['row1', 'row2', 'row3', 'row4', 'row5']
data1 = {'col1': ['Dog', 'Cat', 'Cat', 'Cat', 'Cat'],
'col2': ['Cat', 'Dragon', 'Dog', 'Tree', 'Tree'],
'col3': ['Bird', 'Bird', 'Bird', 'Bird', 'Monkey'],
'col4': ['Tree', 'Dog', 'Tree', 'Ant', 'Dragon'],
'col5': ['Lion', 'Tree', 'Hippo', 'Fish', 'Ant']}
data2 = {'col1': [3.219843, 2.8661892, 2.5679462, 3.631389, 2.4727197],
'col2': [1.3631996, 1.4396228, 1.3657334, 0.94815284, 1.5941181],
'col3': [1.0051135, 0.7863044, 0.9470184, 0.7561722, 1.4069512],
'col4': [0.89303696, 0.539315, 0.79186934, 0.6743943, 1.064051],
'col5': [0.4313375, 0.48167187, 0.48637152, 0.5441728, 0.48297918]}
df1 = pd.DataFrame(data1, index=index)
df2 = pd.DataFrame(data2, index=index)
Поскольку вы не указали, какая структура данных вам нужна, это стратегия, изложенная выше в понимании dict
:
{animal: df2[df1.eq(animal)].stack().values for animal in np.unique(df1)}
Результат выглядит следующим образом:
{'Ant': array([0.6743943 , 0.48297918]),
'Bird': array([1.0051135, 0.7863044, 0.9470184, 0.7561722]),
'Cat': array([1.3631996, 2.8661892, 2.5679462, 3.631389 , 2.4727197]),
'Dog': array([3.219843 , 0.539315 , 1.3657334]),
'Dragon': array([1.4396228, 1.064051 ]),
'Fish': array([0.5441728]),
'Hippo': array([0.48637152]),
'Lion': array([0.4313375]),
'Monkey': array([1.4069512]),
'Tree': array([0.89303696, 0.48167187, 0.79186934, 0.94815284, 1.5941181 ])}
Спасибо за предоставленные конструкторы. Что касается вашего ответа, имейте в виду, что будет неэффективно повторно фильтровать фрейм данных для каждого животного (сложность O (n * m), когда вы можете достичь этого за O (n)).
Предполагая, что @fsimonjetz любезно предоставил ввод, вы можете stack
оба фрейма данных, а затем GroupBy.agg
в виде списка:
df2.stack().groupby(df1.stack()).agg(list).to_dict()
или, используя промежуточный DataFrame:
(pd
.concat([df1.stack(),df2.stack()], axis=1)
.groupby(0)[1].agg(list)
.to_dict()
)
выход:
{'Ant': [0.6743943, 0.48297918],
'Bird': [1.0051135, 0.7863044, 0.9470184, 0.7561722],
'Cat': [1.3631996, 2.8661892, 2.5679462, 3.631389, 2.4727197],
'Dog': [3.219843, 0.539315, 1.3657334],
'Dragon': [1.4396228, 1.064051],
'Fish': [0.5441728],
'Hippo': [0.48637152],
'Lion': [0.4313375],
'Monkey': [1.4069512],
'Tree': [0.89303696, 0.48167187, 0.79186934, 0.94815284, 1.5941181]}
Рад помочь! Кстати, я узнаю много из ваших постов, и этот не исключение, так что предоставление конструкторов не было полностью самоотверженным поступком, ха-ха.
Являются ли имена столбцов df1 и df2 для первых столбцов или имен фреймов данных?