पांडा में कार्टेसियन उत्पाद


107

मेरे पास दो पांडा डेटाफ्रेम हैं:

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

उनके कार्टेशियन उत्पाद को प्राप्त करने के लिए सबसे अच्छा अभ्यास क्या है (निश्चित रूप से इसे मेरी तरह स्पष्ट रूप से लिखे बिना)?

#df1, df2 cartesian product
df_cartesian = DataFrame({'col1':[1,2,1,2],'col2':[3,4,3,4],'col3':[5,5,6,6]})

जवाबों:


88

यदि आपके पास एक कुंजी है जिसे प्रत्येक पंक्ति के लिए दोहराया जाता है, तो आप मर्ज का उपयोग करके कार्टेसियन उत्पाद का उत्पादन कर सकते हैं (जैसे आप 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']]

आउटपुट:

   col1  col2  col3
0     1     3     5
1     1     3     6
2     2     4     5
3     2     4     6

प्रलेखन के लिए यहाँ देखें: http://pandas.pydata.org/pandas-docs/stable/merging.html#brief-primer-on-merge-methods-relational-algebra


6
तो यह ठीक से करने के लिए पहले एक अप्रयुक्त स्तंभ नाम ढूंढना होगा, फिर उस नाम के साथ डमी कॉलम जोड़ें, विलय करें, और परिणाम पर कॉलम को छोड़ दें? बनाना, पढ़ने के विपरीत, पंडों के साथ डेटा सिर्फ एक दर्द है
Bananach

68

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()

बाहर:

   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

6
मेरा मानना ​​है कि पंडों के लिए यह इन दिनों सबसे ज्यादा पंडों की तरह है = = 0.21
shadi

6
आपके पास डाउनवोट्स हैं क्योंकि आपने यह नहीं दिखाया है कि यह 1 से अधिक कॉलम वाले किसी भी चीज़ के लिए कैसे सामान्य हो रहा है।
cs95

यह फ़ंक्शन ( stackoverflow.com/a/58242079/1840471 ) इसे आर्सेज़ की एक श्रंखला का उपयोग करके मनमानी संख्या की सूची में सामान्यीकृत करता है। यह सवाल यहाँ है, जो दो DataFrames की कार्तीय उत्पाद लेता है (यानी यह उत्पाद नहीं ले रही है से थोड़ा अलग है df1.col1और df.col2)।
मैक्स गनीस

वास्तव में मुझे नहीं लगता कि from_productइस समस्या के लिए इस्तेमाल किया जा सकता है।
मैक्स गनीस

34

यह एक कोड गोल्फ प्रतियोगिता नहीं जीतेगा, और पिछले उत्तरों से उधार लेगा - लेकिन यह स्पष्ट रूप से दिखाता है कि कुंजी को कैसे जोड़ा जाता है, और कैसे काम करता है। यह सूचियों से 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)

25
थोड़ा छोटा संस्करण:days_and_stores = pd.merge(days.assign(key=0), stores.assign(key=0), on='key').drop('key', axis=1)
यूजीन पखोमोव

आप क्रॉसजॉइन का उल्लेख करते हैं, लेकिन आप एक स्पंदन डेटाफ्रेम का उपयोग कर रहे हैं, स्पार्क डेटाफ्रेम का नहीं।
ब्रायस गिंटा

डैंग। सोच नहीं रहा था मैं अक्सर स्पार्क + पांडा का एक साथ उपयोग करता हूं, जब मैंने इस पोस्ट के बारे में सोचा कि स्पार्क के अपडेट को देखा। धन्यवाद ब्रायस।
रोब गुडरियन

32

इसके लिए न्यूनतम कोड आवश्यक है। कार्टेजियन के लिए एक आम 'की' बनाएं दो को मर्ज करें:

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

df_cartesian = df1.merge(df2, how='outer')

8
+ df_cartesian = df_cartesian.drop(columns=['key'])अंत में साफ करने के लिए
स्टैकजी

22

विधि जंजीर के साथ:

product = (
    df1.assign(key=1)
    .merge(df2.assign(key=1), on="key")
    .drop("key", axis=1)
)

14

एक विकल्प के रूप में, एक व्यक्ति इटर्लस द्वारा प्रदान किए गए कार्टेशियन उत्पाद पर भरोसा कर सकता है: 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

4
मैंने यह परीक्षण किया और यह काम करता है, लेकिन यह बड़े डेटासेट के लिए मर्ज जवाबों की तुलना में बहुत धीमा है।
MrJ

2

यदि आपके पास ओवरलैपिंग कॉलम नहीं हैं, तो एक जोड़ना नहीं चाहते हैं, और डेटा फ़्रेम के सूचक को छोड़ दिया जा सकता है, यह आसान हो सकता है:

df1.index[:] = df2.index[:] = 0
df_cartesian = df1.join(df2, how='outer')
df_cartesian.index[:] = range(len(df_cartesian))

1
यह आशाजनक लग रहा है - लेकिन मुझे पहली पंक्ति में त्रुटि मिलती है: TypeError: '<class 'pandas.core.index.Int64Index'>' does not support mutable operations. मैं , index=[0,0]डेटाफ़्रेम परिभाषा में जोड़कर इसके चारों ओर प्राप्त कर सकता हूं ।
रेसिंग टैडपोल

2
या df1 = df1.set_index([[0]*len(df1)]))(और इसी तरह के लिए df2) का उपयोग कर ।
रेसिंग टैडपोल

रेसिंग टैडपोल के संपादन ने मेरे लिए यह काम किया - धन्यवाद!
सेविन्स

2

यहां दो डेटा फ़्रेम के साथ एक सरल कार्टेशियन उत्पाद करने के लिए एक सहायक कार्य है। आंतरिक तर्क एक आंतरिक कुंजी का उपयोग करके संभालता है, और किसी भी स्तंभ को प्रबंधित करने से बचता है जिसे दोनों ओर से "कुंजी" नाम दिया जाता है।

import pandas as pd

def cartesian(df1, df2):
    """Determine Cartesian product of two data frames."""
    key = 'key'
    while key in df1.columns or key in df2.columns:
        key = '_' + key
    key_d = {key: 0}
    return pd.merge(
        df1.assign(**key_d), df2.assign(**key_d), on=key).drop(key, axis=1)

# Two data frames, where the first happens to have a 'key' column
df1 = pd.DataFrame({'number':[1, 2], 'key':[3, 4]})
df2 = pd.DataFrame({'digit': [5, 6]})
cartesian(df1, df2)

दिखाता है:

   number  key  digit
0       1    3      5
1       1    3      6
2       2    4      5
3       2    4      6

क्या दोहरा लिया जब मैंने देखा कि एक 7 साल के सवाल का 4 घंटे पुराना जवाब था - इसके लिए बहुत बहुत धन्यवाद :)
ब्रूनो ई

0

आप कार्टेसियन उत्पाद लेकर शुरू कर सकते हैं df1.col1और df2.col3फिर df1प्राप्त करने के लिए वापस विलय कर सकते हैं col2

यहां एक सामान्य कार्टेशियन उत्पाद फ़ंक्शन है जो सूचियों का शब्दकोश लेता है:

def cartesian_product(d):
    index = pd.MultiIndex.from_product(d.values(), names=d.keys())
    return pd.DataFrame(index=index).reset_index()

इस रूप में लागू करें:

res = cartesian_product({'col1': df1.col1, 'col3': df2.col3})
pd.merge(res, df1, on='col1')
#  col1 col3 col2
# 0   1    5    3
# 1   1    6    3
# 2   2    5    4
# 3   2    6    4

0

आप तेजी से हो सकता है के रूप में सुन्न का उपयोग कर सकते हैं। मान लीजिए कि आपके पास दो श्रृंखलाएं हैं,

s1 = pd.Series(np.random.randn(100,))
s2 = pd.Series(np.random.randn(100,))

आपको केवल ज़रूरत है,

pd.DataFrame(
    s1[:, None] @ s2[None, :], 
    index = s1.index, columns = s2.index
)

-1

मुझे लगता है कि पांडा मल्टीआंडेक्स का उपयोग करना नौकरी के लिए सबसे अच्छा साधन है। यदि आपके पास परिणाम पर सूचियों lists_list, कॉल pd.MultiIndex.from_product(lists_list)और पुनरावृति की सूची है (या डेटाफ्रैम इंडेक्स में इसका उपयोग करें)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.