В этой статье подробно объясняется использование метода transform() в пандах.
официальное объяснение
DataFrame.transform(self, func, axis=0, *args, **kwargs) → 'DataFrame'[source]
Call func on self producing a DataFrame with transformed values.
Produced DataFrame will have same axis length as self.
- funcfunction, str, list or dict Function to use for transforming the data. If a function, must either work when passed a DataFrame or when passed to DataFrame.apply.
Accepted combinations are:
- function
-
string function name
-
list of functions and/or function names, e.g. [np.exp. 'sqrt']
-
dict of axis labels -> functions, function names or list of such.
- axis
{0 или "индекс", 1 или "столбцы"}, по умолчанию 0 Если 0 или «индекс»: применить функцию к каждому столбцу Если 1 или «столбцы»: применить функцию к каждой строке.
- *args
Positional arguments to pass to func.
- **kwargs
Keyword arguments to pass to func.
- Возвращает: DataFrame
A DataFrame that must have the same length as self.
- Выдает: ValueError
If the returned DataFrame has a different length than self.
import numpy as np
import pandas as pd
метод преобразования
Функции
Метод преобразования обычно используется в сочетании с методом группировки.
- Генерирует скалярное значение и транслирует его в данные о размере каждого пакета
- преобразование может создать объект того же размера, что и вход
- преобразование не может изменить свой ввод
df = pd.DataFrame({
"key":["a","b","c"] * 4,
"values":np.arange(12.0)
})
df
key | values | |
---|---|---|
0 | a | 0.0 |
1 | b | 1.0 |
2 | c | 2.0 |
3 | a | 3.0 |
4 | b | 4.0 |
5 | c | 5.0 |
6 | a | 6.0 |
7 | b | 7.0 |
8 | c | 8.0 |
9 | a | 9.0 |
10 | b | 10.0 |
11 | c | 11.0 |
группировка
g = df.groupby("key").values # 分组再求平均
g.mean()
key
a 4.5
b 5.5
c 6.5
Name: values, dtype: float64
трансформировать использование
Каждая позиция заменяется средним
передать анонимную функцию
g.transform(lambda x:x.mean())
0 4.5
1 5.5
2 6.5
3 4.5
4 5.5
5 6.5
6 4.5
7 5.5
8 6.5
9 4.5
10 5.5
11 6.5
Name: values, dtype: float64
Передать псевдоним строки функции в методе agg
Встроенная функция агрегирования напрямую передает псевдоним max\min\sum\mean
g.transform("mean")
0 4.5
1 5.5
2 6.5
3 4.5
4 5.5
5 6.5
6 4.5
7 5.5
8 6.5
9 4.5
10 5.5
11 6.5
Name: values, dtype: float64
transform используется с функциями, которые возвращают S
g.transform(lambda x:x * 2)
0 0.0
1 2.0
2 4.0
3 6.0
4 8.0
5 10.0
6 12.0
7 14.0
8 16.0
9 18.0
10 20.0
11 22.0
Name: values, dtype: float64
Убывающий рейтинг
g.transform(lambda x:x.rank(ascending=False))
0 4.0
1 4.0
2 4.0
3 3.0
4 3.0
5 3.0
6 2.0
7 2.0
8 2.0
9 1.0
10 1.0
11 1.0
Name: values, dtype: float64
Аналогично функции применения
Передайте функции непосредственно для преобразования
def normalize(x):
return (x - x.mean()) / x.std()
g.transform(normalize)
0 -1.161895
1 -1.161895
2 -1.161895
3 -0.387298
4 -0.387298
5 -0.387298
6 0.387298
7 0.387298
8 0.387298
9 1.161895
10 1.161895
11 1.161895
Name: values, dtype: float64
g.apply(normalize) # 结果同上
0 -1.161895
1 -1.161895
2 -1.161895
3 -0.387298
4 -0.387298
5 -0.387298
6 0.387298
7 0.387298
8 0.387298
9 1.161895
10 1.161895
11 1.161895
Name: values, dtype: float64
нормализованный экземпляр
normalized = (df["values"] - g.transform("mean")) / g.transform("std") # 内置的聚合函数直接传递
normalized
0 -1.161895
1 -1.161895
2 -1.161895
3 -0.387298
4 -0.387298
5 -0.387298
6 0.387298
7 0.387298
8 0.387298
9 1.161895
10 1.161895
11 1.161895
Name: values, dtype: float64
Официальный пример
df = pd.DataFrame({'A': range(3), 'B': range(1, 4)})
df
A | B | |
---|---|---|
0 | 0 | 1 |
1 | 1 | 2 |
2 | 2 | 3 |
df.transform(lambda x:x+1) # 每个元素+1
A | B | |
---|---|---|
0 | 1 | 2 |
1 | 2 | 3 |
2 | 3 | 4 |
s = pd.Series(range(3))
s
0 0
1 1
2 2
dtype: int64
s.transform([np.sqrt, np.exp]) # 传入函数即可
sqrt | exp | |
---|---|---|
0 | 0.000000 | 1.000000 |
1 | 1.000000 | 2.718282 |
2 | 1.414214 | 7.389056 |
Understanding the Transform Function in Pandas
На этом сайте есть полный пример, объясняющий использование метода преобразования.
Необработанные данные
решение проблем
You can see in the data that the file contains 3 different orders (10001, 10005 and 10006) and that each order consists has multiple products (aka skus).
Вопрос, на который мы хотели бы ответить: «Какой процент от общей суммы заказа составляет каждый артикул?»
For example, if we look at order 10001 with a total of $576.12, the break down would be:
- B1-20000 = $235.83 or 40.9%
- S1-27722 = $232.32 or 40.3%
- B1-86481 = $107.97 or 18.7%
Найдите соотношение цен разных товаров в заказе
традиционный метод
Сначала найдите значение столбца пропорций, а затем объедините с исходными данными.
import pandas as pd
df = pd.read_excel("sales_transactions.xlsx")
df.groupby('order')["ext price"].sum()
order
10001 576.12
10005 8185.49
10006 3724.49
Name: ext price, dtype: float64
order_total = df.groupby('order')["ext price"].sum().rename("Order_Total").reset_index() # 添加Order_Total列属性的值
df_1 = df.merge(order_total) # 合并原始数据df和order_total数据
df_1["Percent_of_Order"] = df_1["ext price"] / df_1["Order_Total"] # 添加Percent_of_Order
использовать преобразование
Transform + groupby используются вместе: сначала группа, а затем сумма