Расширенное использование Pandas - метод преобразования

pandas

В этой статье подробно объясняется использование метода 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 используются вместе: сначала группа, а затем сумма

Графическое преобразование