Сравните несколько Pandas DataFrames для сопоставления значений - PullRequest
0 голосов
/ 24 марта 2020

Я пытаюсь получить ежемесячный анализ автосервиса, чтобы сообщить о пробеге автомобилей в его парке.

У меня есть отчеты, основанные на Excel, и я хочу использовать Pandas для вывода широкой таблицы с отчетами об использовании автомобиля в милях за отчетные месяцы.

Например, у меня есть отчеты за январь, февраль, март и апрель. Каждый автомобиль имеет уникальный идентификационный номер транспортного средства (VIN), и каждый месяц накапливает мили или нет. Если автомобиль не используется, он не включается в отчет. Отчеты за январь - апрель выглядят примерно так:

Январь:

df_jan
+------+---------+----------+
| VIN  | Mileage |    HQ    |
+------+---------+----------+
| 1111 |     700 | Seattle  |
| 1112 |     250 | Seattle  |
| 1113 |     640 | Portland |
+------+---------+----------+

Февраль:

df_feb
+------+---------+----------+
| VIN  | Mileage |    HQ    |
+------+---------+----------+
| 1111 |     220 | Seattle  |
| 1112 |     860 | Seattle  |
| 1114 |     120 | Portland |
| 1115 |     520 | Portland |
| 1116 |     100 | Seattle  |
+------+---------+----------+

Март:

df_mar
+------+---------+----------+
| VIN  | Mileage |    HQ    |
+------+---------+----------+
| 1111 |      20 | Seattle  |
| 1112 |      40 | Seattle  |
| 1114 |     350 | Portland |
| 1116 |     140 | Seattle  |
| 1117 |      50 | Seattle  |
+------+---------+----------+

Апрель:

df_apr
+------+---------+----------+
| VIN  | Mileage |    HQ    |
+------+---------+----------+
| 1112 |     430 | Seattle  |
| 1114 |     140 | Portland |
| 1116 |     420 | Seattle  |
| 1117 |     530 | Seattle  |
| 1118 |     220 | Bellevue |
+------+---------+----------+

Результат, к которому я стремлюсь, показывает столбец для каждого месяца, с учетом пробега, если пробег автомобиля за этот месяц:

df_final
+------+-------------+-------------+-------------+-------------+----------+
| VIN  | Jan Mileage | Feb Mileage | Mar Mileage | Apr Mileage |    HQ    |
+------+-------------+-------------+-------------+-------------+----------+
| 1111 |         700 |         220 |          20 |             | Seattle  |
| 1112 |         250 |         860 |          40 |         430 | Seattle  |
| 1113 |         640 |             |             |             | Portland |
| 1114 |             |         120 |         350 |         140 | Portland |
| 1115 |             |         520 |             |             | Portland |
| 1116 |             |         100 |         140 |         420 | Seattle  |
| 1117 |             |             |          50 |         530 | Seattle  |
| 1118 |             |             |             |         220 | Bellevue |
+------+-------------+-------------+-------------+-------------+----------+

Как только я получу это, Я могу составить график и сообщить пробег с течением времени в сжатой форме

Как я могу сравнить значения VIN (где VIN , а не индекс с DataFrame ()) и получить пробег за каждый месяц в соответствующем столбце? Я могу перебрать первый DataFrame (январь) и определить, существует ли значение во втором DataFrame (февраль). Но я стараюсь избегать множества вложенных циклов.

Существует ли встроенный метод или общеизвестный шаблон для итерации по каждому из фреймов данных без предварительного предоставления списка значений для поиска, который может идентифицировать индексы в каждом фрейме данных, а также обновлять или пропустить ячейки строки в зависимости от того, было ли найдено это значение или нет?

Ответы [ 2 ]

1 голос
/ 24 марта 2020

Другой способ использования pandas .merge и functools уменьшает , чтобы получить одно соединение лайнера:

# imports
import pandas as pd
from functools import reduce

# define dataframes
df_jan = pd.DataFrame({"VIN": [1111, 1112, 1113], 
                       "Mileage": [700, 250, 640],
                       "HQ": ["Seattle", "Seattle", "Portland"]})

df_feb = pd.DataFrame({"VIN": [1111, 1112, 1114, 1115, 1116],
                       "Mileage": [220, 860, 120, 520, 100],
                       "HQ": ["Seattle", "Seattle", "Portland", "Portland", "Seattle"]})

df_mar = pd.DataFrame({"VIN": [1111, 1112, 1114, 1116, 1117], 
                       "Mileage": [20, 40, 350, 140, 50],
                       "HQ": ["Seattle", "Seattle", "Portland", "Seattle", "Seattle"]})

df_apr = pd.DataFrame({"VIN": [1112, 1114, 1116, 1117, 1118], 
                       "Mileage": [430, 140, 420, 530, 220],
                       "HQ": ["Seattle", "Portland", "Seattle", "Seattle", "Bellevue"]})

# create a list of dataframes and a list of months
dfs = [df_jan, df_feb, df_mar, df_apr]
months = ['Jan', 'Feb', 'Mar', 'Apr']

# ranmes Mileage column
for df, m in zip(dfs, months):
    df.rename(columns={'Mileage':f'Mileage_{m}'}, inplace=True)

# Join all dataframes
df_final = reduce(lambda left,right: pd.merge(left,right,on=['VIN', 'HQ'], how='outer'), dfs)

# check result
df_final
   VIN  Mileage_Jan        HQ  Mileage_Feb  Mileage_Mar  Mileage_Apr
0  1111        700.0   Seattle        220.0         20.0          NaN
1  1112        250.0   Seattle        860.0         40.0        430.0
2  1113        640.0  Portland          NaN          NaN          NaN
3  1114          NaN  Portland        120.0        350.0        140.0
4  1115          NaN  Portland        520.0          NaN          NaN
5  1116          NaN   Seattle        100.0        140.0        420.0
6  1117          NaN   Seattle          NaN         50.0        530.0
7  1118          NaN  Bellevue          NaN          NaN        220.0
0 голосов
/ 24 марта 2020

См. https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html.

import pandas as pd

df_jan = pd.DataFrame({"VIN": [1111, 1112, 1113], "Mileage": [700, 250, 640],
                       "HQ": ["Seattle", "Seattle", "Portland"]})

df_feb = pd.DataFrame({"VIN": [1111, 1112, 1114, 1115, 1116], "Mileage": [220, 860, 120, 520, 100],
                       "HQ": ["Seattle", "Seattle", "Portland", "Portland", "Seattle"]})

df_mar = pd.DataFrame({"VIN": [1111, 1112, 1114, 1116, 1117], "Mileage": [20, 40, 350, 140, 50],
                       "HQ": ["Seattle", "Seattle", "Portland", "Seattle", "Seattle"]})

df_apr = pd.DataFrame({"VIN": [1112, 1114, 1116, 1117, 1118], "Mileage": [430, 140, 420, 530, 220],
                       "HQ": ["Seattle", "Portland", "Seattle", "Seattle", "Bellevue"]})

df = pd.DataFrame(columns=["VIN", "HQ"])

df = pd.merge(left=df, right=df_jan, on=["VIN", "HQ"], how="outer")
df.rename(columns={"Mileage": "Jan Mileage"}, inplace=True)

df = pd.merge(left=df, right=df_feb, on=["VIN", "HQ"], how="outer")
df.rename(columns={"Mileage": "Feb Mileage"}, inplace=True)

df = pd.merge(left=df, right=df_mar, on=["VIN", "HQ"], how="outer")
df.rename(columns={"Mileage": "Mar Mileage"}, inplace=True)

df = pd.merge(left=df, right=df_apr, on=["VIN", "HQ"], how="outer")
df.rename(columns={"Mileage": "Apr Mileage"}, inplace=True)

df = df[["VIN", "Jan Mileage", "Feb Mileage", "Mar Mileage", "Apr Mileage", "HQ"]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...