У меня есть два длинных фрейма данных:
df1 = pd.DataFrame([[1, 1],
[2, 1],
[3, 1],
[2, 1],
[2, 2],
[3, 2],
[5, 3]], columns=['value', 'id'])
df2 = pd.DataFrame([1, 2, 3, 4])
Первый столбец df1
действует как значение, а второй столбец является столбцом ID
.
Я хочу умножить df1
на df2
, первое значение каждого ID
умножается на первое значение df2
, второе значение умножается на второе и так далее. Так, например, для id=1
мы получим [1x1=1, 2x2=4, 3x3=9, 4x2=8]
, для id=2
мы получим [2x1=2, 3x2=6]
,... Гарантируется, что значения для каждого ID
не превышают длину df2
, и в конечном итоге результат будет чем-то вроде
1
4
9
8
2
6
5
код
out = df1.groupby('id').cumcount().map(df2[0]).mul(df1['value'])
вне
0 1
1 4
2 9
3 8
4 2
5 6
6 5
dtype: int64
Комментарий @wjandrea:
Перечислите каждую группу id
, используйте их для индексации в df2[0]
, а затем умножьте.
Хороший! Однако было бы полезно добавить краткое объяснение, например: «Перечислите каждую группу id
, используйте их для индексации в df2[0]
, а затем умножьте». Обязательно используйте это, если хотите.
Попробуй это:
df2 = df2.rename(columns = {0: "M"})
df1['mindex'] = df1.groupby('id').cumcount().values
df1['multiplier'] = df2.M.values[df1['mindex']]
df1['product'] = df1['value'] * df1['multiplier']
df1
Или однострочник:
# if you don't want to rename the column in df2
df1['value'] * df2[0].values[df1.groupby('id').cumcount().values]
Для столбца df1
: вам нужен механизм для подсчета количества вхождений (со сдвигом -1, начиная с 0, 1, 2, ...) id
: тогда четыре 1
будут 0, 1, 2. , 3; следующие два появления 2
в столбце id
будут 0, 1, а последние 3 будут просто 0.
Преимущество этих значений (сдвинутых на -1) заключается в том, что теперь они могут выступать в качестве индекса значений, которые мы получаем из df2
.
Мы вычисляем эти индексы с помощью df1.groupby('id').cumcount().values
, который возвращает массив [0, 1, 2, 3, 1, 2, 1]
. Это хранится в столбце mindex
.
Наконец, когда мы помещаем эти индексы внутрь df2.M
(мы переименовали столбец 0
в M
), он возвращает желаемый набор множителей.
Умножение столбцов value
и multiplier
дает результат в столбце product
.
Результат:
Вам не нужно добавлять multiplier
к df... Вы просто используете его для иллюстрации?
Зачем переименовывать df2[0]
? С тем же успехом ты мог бы это сделать df2[0].values...
Да, здесь оно использовано просто для иллюстрации. Все это можно сделать в один ряд.
@wjandrea Колонку именования желательно писать с помощью letters
, а не numbers
. Если бы я был ОП, я бы назвал этот столбец как-нибудь более осмысленным. Я знаю, что df2[0].values
можно использовать. Я хотел показать, что именованные столбцы имеют преимущество использования нотации df2.M
.
Справедливо. Я сам не использую и не рекомендую точечную нотацию, поскольку она имеет много недостатков (см. предупреждение в разделе Доступ к атрибутам).
@ScaryWombat Это первое значение с
id=3
, поэтому оно будет умножено на первое значение вdf2
, и получится 5x1=5