Объединение двух фреймов данных, итерация по значениям второго блока данных [дубликат]

Вот один из способов добавить материал в реестр в классе RouteBuilder. Ниже я добавляю TCPServerInitializerFactory, который будет использоваться позже. Я всегда использую архетип верблюда, но создаю маршруты, используя java dsl. Это отлично работает для меня.

TCPServerInitializerFactory serverFactory = new TCPServerInitializerFactory(null);
final CamelContext camelContext = getContext();
        final org.apache.camel.impl.SimpleRegistry registry = new org.apache.camel.impl.SimpleRegistry();
        final org.apache.camel.impl.CompositeRegistry compositeRegistry = new org.apache.camel.impl.CompositeRegistry();
        compositeRegistry.addRegistry(camelContext.getRegistry());
        compositeRegistry.addRegistry(registry);
        ((org.apache.camel.impl.DefaultCamelContext) camelContext).setRegistry(compositeRegistry);
    registry.put("spf", serverFactory);
54
задан joaquin 7 November 2012 в 14:54
поделиться

9 ответов

Если у вас есть ключ, который повторяется для каждой строки, вы можете создать декартово произведение с использованием слияния (как в SQL).

from pandas import DataFrame, merge
df1 = DataFrame({'key':[1,1], 'col1':[1,2],'col2':[3,4]})
df2 = DataFrame({'key':[1,1], 'col3':[5,6]})

merge(df1, df2,on='key')[['col1', 'col2', 'col3']]

См. здесь документацию: http://pandas.pydata.org/pandas-docs/stable/merging.html#brief-primer-on-merge-methods-relational-algebra

47
ответ дан Matti John 21 August 2018 в 15:03
поделиться
  • 1
    я надеялся, что есть более чистый API, а не добавление столбца, но он делает работу, спасибо – user1087310 7 November 2012 в 14:54

Минимальный код, необходимый для этого. Создайте общий «ключ» для декартовой слияния двух:

df1['key'] = 0
df2['key'] = 0

df_cartesian = df1.merge(df2, how='outer')
5
ответ дан A.Kot 21 August 2018 в 15:03
поделиться

Я считаю, что использование pandas MultiIndex является лучшим инструментом для работы. Если у вас есть список списков lists_list, вызовите pd.MultiIndex.from_product(lists_list) и повторите результат (или используйте его в индексе DataFrame).

-1
ответ дан Ankur Kanoria 21 August 2018 в 15:03
поделиться

Используйте pd.MultiIndex.from_product в качестве индекса в противном случае пустой фреймворк, а затем сбросьте его индекс, и все готово.

a = [1, 2, 3]
b = ["a", "b", "c"]

index = pd.MultiIndex.from_product([a, b], names = ["a", "b"])

pd.DataFrame(index = index).reset_index()

out:

   a  b
0  1  a
1  1  b
2  1  c
3  2  a
4  2  b
5  2  c
6  3  a
7  3  b
8  3  c
4
ответ дан Gijs 21 August 2018 в 15:03
поделиться
  • 1
    Я считаю, что в наши дни это самый панда-способ для панд & gt; = 0,21 – shadi 23 April 2018 в 06:05
  • 2
    Да, для этого у меня есть даже некоторые downvotes, но я думаю, что это работает очень хорошо. – Gijs 24 April 2018 в 07:21
  • 3
    Не слушайте голоса – shadi 24 April 2018 в 08:22

С цепью метода:

product = (
    df1.assign(key=1)
    .merge(df2.assign(key=1), on="key")
    .drop("key", axis=1)
)
2
ответ дан pomber 21 August 2018 в 15:03
поделиться

Это не приведет к конкуренции в кодовом гольф-соревновании и заимствует предыдущие ответы, но ясно показывает, как добавляется ключ и как работает соединение. Это создает 2 новых фрейма данных из списков, а затем добавляет ключ для декартового продукта.

Моим вариантом использования было то, что мне понадобился список всех идентификаторов магазина в течение каждой недели в моем списке. Итак, я создал список всех недель, которые я хотел иметь, а затем список всех идентификаторов хранилища, которые я хотел сопоставить им.

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

days = pd.DataFrame({'date':list_of_days})
stores = pd.DataFrame({'store_id':list_of_stores})
stores['key'] = 0
days['key'] = 0
days_and_stores = days.merge(stores, how='left', on = 'key')
days_and_stores.drop('key',1, inplace=True)
19
ответ дан Rob Guderian 21 August 2018 в 15:03
поделиться
  • 1
    Немного короче версия: days_and_stores = pd.merge(days.assign(key=0), stores.assign(key=0), on='key').drop('key', axis=1) – Eugene Pakhomov 11 March 2017 в 16:59
  • 2
    Вы упоминаете crossJoin, но вы используете рамку данных pandas, а не блок данных искры. – Bryce Guinta 17 April 2017 в 04:44
  • 3
    Dang. Не думал. Я часто использую искру + панды так часто, что, увидев обновление, я подумал об этом посту. Спасибо, Брайс. – Rob Guderian 18 April 2017 в 14:10

Если у вас нет перекрывающихся столбцов, не хотите их добавлять, а индексы кадров данных могут быть отброшены, это может быть проще:

df1.index[:] = df2.index[:] = 0
df_cartesian = df1.join(df2, how='outer')
df_cartesian.index[:] = range(len(df_cartesian))
0
ответ дан sergeyk 21 August 2018 в 15:03
поделиться
  • 1
    Это выглядит многообещающе, но я получаю ошибку в первой строке: TypeError: '<class 'pandas.core.index.Int64Index'>' does not support mutable operations. Я могу обойти это, добавив , index=[0,0] к определению dataframe. – Racing Tadpole 22 May 2014 в 01:19
  • 2
    Или используя df1 = df1.set_index([[0]*len(df1)])) (и аналогично для df2). – Racing Tadpole 22 May 2014 в 01:42
  • 3
    Редактирование гоночных головокружений сделало эту работу для меня - спасибо! – Sevyns 10 March 2017 в 22:19

В качестве альтернативы можно полагаться на декартово произведение, предоставляемое itertools: itertools.product, что позволяет избежать создания временного ключа или изменения индекса:

import numpy as np 
import pandas as pd 
import itertools

def cartesian(df1, df2):
    rows = itertools.product(df1.iterrows(), df2.iterrows())

    df = pd.DataFrame(left.append(right) for (_, left), (_, right) in rows)
    return df.reset_index(drop=True)

Быстрая проверка:

In [46]: a = pd.DataFrame(np.random.rand(5, 3), columns=["a", "b", "c"])

In [47]: b = pd.DataFrame(np.random.rand(5, 3), columns=["d", "e", "f"])    

In [48]: cartesian(a,b)
Out[48]:
           a         b         c         d         e         f
0   0.436480  0.068491  0.260292  0.991311  0.064167  0.715142
1   0.436480  0.068491  0.260292  0.101777  0.840464  0.760616
2   0.436480  0.068491  0.260292  0.655391  0.289537  0.391893
3   0.436480  0.068491  0.260292  0.383729  0.061811  0.773627
4   0.436480  0.068491  0.260292  0.575711  0.995151  0.804567
5   0.469578  0.052932  0.633394  0.991311  0.064167  0.715142
6   0.469578  0.052932  0.633394  0.101777  0.840464  0.760616
7   0.469578  0.052932  0.633394  0.655391  0.289537  0.391893
8   0.469578  0.052932  0.633394  0.383729  0.061811  0.773627
9   0.469578  0.052932  0.633394  0.575711  0.995151  0.804567
10  0.466813  0.224062  0.218994  0.991311  0.064167  0.715142
11  0.466813  0.224062  0.218994  0.101777  0.840464  0.760616
12  0.466813  0.224062  0.218994  0.655391  0.289537  0.391893
13  0.466813  0.224062  0.218994  0.383729  0.061811  0.773627
14  0.466813  0.224062  0.218994  0.575711  0.995151  0.804567
15  0.831365  0.273890  0.130410  0.991311  0.064167  0.715142
16  0.831365  0.273890  0.130410  0.101777  0.840464  0.760616
17  0.831365  0.273890  0.130410  0.655391  0.289537  0.391893
18  0.831365  0.273890  0.130410  0.383729  0.061811  0.773627
19  0.831365  0.273890  0.130410  0.575711  0.995151  0.804567
20  0.447640  0.848283  0.627224  0.991311  0.064167  0.715142
21  0.447640  0.848283  0.627224  0.101777  0.840464  0.760616
22  0.447640  0.848283  0.627224  0.655391  0.289537  0.391893
23  0.447640  0.848283  0.627224  0.383729  0.061811  0.773627
24  0.447640  0.848283  0.627224  0.575711  0.995151  0.804567
9
ответ дан Svend 21 August 2018 в 15:03
поделиться
  • 1
    Я тестировал это, и он работает, но он намного медленнее, чем предыдущие ответы на слияние для больших наборов данных. – MrJ 12 February 2018 в 23:36
0
ответ дан piRSquared 1 November 2018 в 08:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: