পান্ডসে কার্টেসিয়ান পণ্য


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

যদি আপনার কাছে এমন একটি কী থাকে যা প্রতিটি সারির জন্য পুনরাবৃত্তি হয় তবে আপনি মার্জ ব্যবহার করে কার্টেসিয়ান পণ্য উত্পাদন করতে পারেন (যেমন আপনি এসকিউএল করতে চান)।

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#b ਸੰর্কিত- প্রাইমার- অন- নিমজ্জন-সম্পর্কিত-সম্পর্কিত সম্পর্কযুক্ত


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 পান্ডাস সবচেয়ে পান্ডাস মত পথ এই দিন
দয়া

6
আপনার ডাউনভিটস রয়েছে কারণ আপনি দেখান নি যে এটি কীভাবে 1 টিরও বেশি কলাম সহ কোনও কিছুর জন্য সাধারণীকরণ করতে চলেছে।
cs95

এই ফাংশন ( স্ট্যাকওভারফ্লো .com/a/58242079/ 1840471 ) এটিকে আর্টস ডিক্ট ব্যবহার করে তালিকার একটি স্বেচ্ছাসেবী সংখ্যায় সাধারণীকরণ করে। এটা তোলে প্রশ্ন এখানে, যা দুই DataFrames এর কার্টিজিয়ান পণ্য লাগে (অর্থাত এটা গুণফল গ্রহণ না থেকে একটু আলাদা df1.col1এবং df.col2)।
ম্যাক্স গেনিস

আসলে আমি মনে করি না যে from_productএই সমস্যার জন্য ব্যবহার করা যেতে পারে।
ম্যাক্স ঘেনিস

34

এটি কোনও কোড গল্ফ প্রতিযোগিতা জিতবে না এবং পূর্ববর্তী উত্তরগুলি থেকে bণ নেবে - তবে কীটি কীভাবে যুক্ত করা হয় এবং কীভাবে যোগদানের কাজ করে তা পরিষ্কারভাবে দেখায়। এটি তালিকা থেকে 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)
ইউজিন পাখোমভ

আপনি ক্রসজাইন উল্লেখ করেছেন, তবে আপনি একটি স্পার্ক ডেটাফ্রেম নয়, একটি পান্ডাস ডেটা ফ্রেম ব্যবহার করছেন।
ব্রাইস গিন্টা

Dang। ভাবছিলাম না। আমি স্পার্ক + পান্ডাস একসাথে প্রায়শই ব্যবহার করি, যখন আমি আপডেটটি স্পার্ক করতে দেখি তখন এই পোস্টটি সম্পর্কে ভাবতাম। ধন্যবাদ ব্রাইস
রব গুডেরিয়ান

32

এটির জন্য ন্যূনতম কোড প্রয়োজন। কার্টেসিয়ান দুটিকে মার্জ করার জন্য একটি সাধারণ 'কী' তৈরি করুন:

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

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

8
+ df_cartesian = df_cartesian.drop(columns=['key'])শেষে পরিষ্কার করতে
StackG

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
আমি এটি পরীক্ষা করেছি এবং এটি কাজ করে, তবে এটি বড় ডেটাসেটের জন্য উপরের মার্জ উত্তরের তুলনায় অনেক ধীর।
মিঃজে

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)এবং ফলাফলটি পুনরাবৃত্তি করুন (বা এটি ডেটাফ্রেম সূচীতে ব্যবহার করুন) use

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.