Слияния и суффиксы Pandas

#python #pandas #dataframe #merge

#python #pandas #фрейм данных #слияние

Вопрос:

Я пишу генератор кода Pandas на основе собственного DSL и сталкиваюсь с проблемой слияний и суффиксов. В SQL доступ к столбцам из результата a JOIN очень прост, потому что на столбцы из JOIN промежуточного результата просто ссылаются через их псевдоним. Например:

 -- dataset_join_node(out, [a, b])
SELECT r1_1.amount AS "sales_vt", r1_2.amount AS "sales_ny", r1_1.amount   r1_2.amount AS "sales_total"
FROM
(
    -- leaf_node(a, fact_sales)
    SELECT ... AS amount
    FROM ...
) AS r1_1
CROSS JOIN
(
    -- leaf_node(b, fact_sales)
    SELECT ... AS amount
    FROM ...
) AS r1_2
  

К сожалению, в Pandas это, по-видимому, не так просто из-за конфликтов столбцов. Кажется, мне нужно использовать suffixes ключевое слово и отслеживать результирующие имена столбцов после выполнения слияний и учитывать любые потенциальные конфликты имен столбцов. Например, мой DSL-запрос (не показан), который выдал SQL, отображенный выше, сгенерировал бы аналогичный код Pandas, подобный этому:

 ...
out_dataset_join_node = (
    a_leaf_node_fact_sales
    .merge(b_leaf_node_fact_sales, how="outer", left_on=["__x"], right_on=["__x"], suffixes=("__1", "__2"))
)

out_dataset_join_node["sales_vt"] = out_dataset_join_node["amount__1"]
out_dataset_join_node["sales_ny"] = out_dataset_join_node["amount__2"]
out_dataset_join_node["sales_total"] = out_dataset_join_node["amount__1"]   out_dataset_join_node["amount__2"]
out_dataset_join_node = out_dataset_join_node[["sales_vt", "sales_ny", "sales_total"]]
...

  

Pandas, похоже, не предоставляет «промежуточный» фрейм данных, в котором я мог бы получить доступ к столбцам с псевдонимом, как это было сделано в SQL выше. В этом примере amount столбец находился в обоих объединяемых фреймах данных, поэтому в игру вступили суффиксы, и мне нужно было знать, что sales_vt это было из результирующего amount__1 столбца и sales_ny было из результирующего amount__2 столбца.

Если мы добавим третий фрейм данных в микс, подход SQL по-прежнему будет простым из-за префикса псевдонима amount столбцов с одинаковыми именами:

 -- dataset_join_node(out, [a, b, c])
SELECT r1_1.amount AS "sales_vt", r1_2.amount AS "sales_ny", r1_3.amount AS "sales_mi",
       r1_1.amount   r1_2.amount   r1_3.amount AS "sales_total"
FROM
(
    -- leaf_node(a, fact_sales)
    SELECT ... AS amount
    FROM ...
) AS r1_1
CROSS JOIN
(
    -- leaf_node(b, fact_sales)
    SELECT ... AS amount
    FROM ...
) AS r1_2
CROSS JOIN
(
    -- leaf_node(c, fact_sales)
    SELECT ... AS amount
    FROM ...
) AS r1_3
  

Но Pandas становится немного сложнее, поскольку последний amount столбец не конфликтует ни с какими предыдущими столбцами, поэтому он попадает в результирующий фрейм данных как just amount (в отличие от двух предыдущих amount столбцов, которые конфликтуют и переименовываются в amount__1 and amount__2 ).

 out_dataset_join_node = (
    a_leaf_node_fact_sales
    .merge(b_leaf_node_fact_sales, how="outer", left_on=["__x"], right_on=["__x"], suffixes=("__1", "__2"))
    .merge(c_leaf_node_fact_sales, how="outer", left_on=["__x"], right_on=["__x"], suffixes=("__3", "__4"))
)

out_dataset_join_node["sales_vt"] = out_dataset_join_node["amount__1"]
out_dataset_join_node["sales_ny"] = out_dataset_join_node["amount__2"]
out_dataset_join_node["sales_mi"] = out_dataset_join_node["amount"]
out_dataset_join_node["sales_total"] = out_dataset_join_node["amount__1"]   out_dataset_join_node["amount__2"]   out_dataset_join_node["amount"]
out_dataset_join_node = out_dataset_join_node[["sales_vt", "sales_ny", "sales_mi", "sales_total"]]
  

Я думаю, что испускаемое suffixes=("__3", "__4") во втором .merge() не нужно, но мой генератор кода еще не настолько умен. 🙂

Мой вопрос в том, есть ли у Pandas другой / лучший способ выполнить аналогичный SQL JOIN , возможно (надеюсь) с помощью способа ссылки на столбцы с помощью псевдонима, аналогичного тому, как SQL позволяет вам получать доступ к столбцам через псевдоним, а затем переименовывать их во все, что вы хотите?

Или Pandas .merge() и suffixes ключевое слово — единственные инструменты в моем распоряжении, и поэтому моему генератору кода необходимо отслеживать возможные конфликты столбцов и генерировать код, как описано выше?

Спасибо за любую информацию.

Комментарии:

1. Привет … эту проблему было бы легче визуализировать, если бы у вас были некоторые образцы данных и структура фрейма данных.

2. Если вы пытаетесь присоединиться к одному столбцу, чтобы получить один столбец взамен. Давайте посмотрим на использование map , однако, если вы «объединяетесь» с несколькими ключами или ожидаете получить несколько столбцов взамен, тогда вам нужно придерживаться join или merge .

3. @ScottBoston да, потенциально объединение нескольких ключей и ожидание возврата нескольких столбцов.