পান্ডাস থ্রি-ওয়ে কলামগুলিতে একাধিক ডেটাফ্রেমে যোগদান করছে


191

আমার কাছে 3 টি সিএসভি ফাইল রয়েছে। প্রত্যেকের কাছে মানুষের (স্ট্রিং) নাম হিসাবে প্রথম কলাম রয়েছে, যখন প্রতিটি ডাটাফ্রেমের অন্যান্য সমস্ত কলামই সেই ব্যক্তির বৈশিষ্ট্য।

আমি কীভাবে তিনটি সিএসভি ডকুমেন্টকে একসাথে একটি করে সিএসভি তৈরির জন্য ব্যক্তির স্ট্রিংয়ের নামের প্রতিটি স্বতন্ত্র মানের জন্য সমস্ত বৈশিষ্ট্যযুক্ত "যুক্ত হতে" পারি?

join()পান্ডাস নির্দিষ্ট করে ফাংশন আমি multiindex প্রয়োজন যে, কিন্তু আমি কি একটি হায়ারারকিকাল ইন্ডেক্স স্কিম একটি যোগদানের একটি একক সূচির উপর ভিত্তি করে উপার্জন কি আছে সম্পর্কে বিভ্রান্ত করছি।


2
আপনার কোনও মাল্টিইন্ডেক্সের দরকার নেই। এতে যোগ দস্তাবেজগুলিতে বলা হয়েছে যে একাধিক কলামগুলিতে যোগদান করার জন্য আপনার যখন কোনও মাল্টিইন্ডেক্স নেই তখন তা এটি পরিচালনা করবে।
cwharland

1
আমার পরীক্ষায়, df1.join([df2, df3], on=[df2_col1, df3_col1])কাজ হয়নি।
লোলারকোস্টার

প্রদত্ত উত্তরের মতো আপনার তাদের একসাথে চেইন করা দরকার। Df1 এবং df2 মার্জ করে তারপরে df3
cwharland

উত্তর:


472

ধরে নেওয়া আমদানি:

import pandas as pd

জন গাল্টের উত্তরটি মূলত একটি reduceঅপারেশন। আমার কাছে যদি হাতে গোনা কয়েকটি ডেটাফ্রেম থাকে তবে আমি এগুলি এ জাতীয় তালিকায় রাখতাম (তালিকা বোঝার বা লুপগুলি বা হোয়াট নোটের মাধ্যমে উত্পন্ন):

dfs = [df0, df1, df2, dfN]

ধরে nameনিলাম তাদের কিছু সাধারণ কলাম রয়েছে, যেমন আপনার উদাহরণের মতো, আমি নিম্নলিখিতটি করব:

df_final = reduce(lambda left,right: pd.merge(left,right,on='name'), dfs)

এইভাবে, আপনার কোডটি যে পরিমাণ সংখ্যক ডেটাফ্রেমে আপনি সংহত করতে চান তা নিয়ে কাজ করা উচিত।

আগস্ট 1, 2016 সম্পাদনা করুন : পাইথন 3: যারা ব্যবহার করছেন তাদের reduceমধ্যে স্থানান্তরিত করা হয়েছে functools। সুতরাং এই ফাংশনটি ব্যবহার করতে, আপনাকে প্রথমে সেই মডিউলটি আমদানি করতে হবে:

from functools import reduce

11
আমি শুধু এই ব্যবহার চেষ্টা এবং এটি ব্যর্থ হয়েছে কারণ reduceপ্রতিস্থাপন করা হয়েছে functools.reduceতাইimport functools functools.reduce(.......)
MattR

3
আমি যুক্ত হতে ক্ষেত্রের নামগুলি পৃথক হলে এই সমাধানটি কীভাবে কাজ করবে? উদাহরণ হিসেবে বলা যায়, তিন ডেটা ফ্রেম আমি থাকতে পারে name1, name2এবং name3যথাক্রমে।
ps0604

2
এর অর্থ এই নয় যে আমাদের n-1একত্রীকরণ ফাংশনে কল রয়েছে? আমি অনুমান করি এই ক্ষেত্রে যেখানে ডেটাফ্রেমগুলির সংখ্যা খুব কম তাতে কিছু আসে যায় না, তবে আমি আরও আশ্চর্য হয়েছি যে এর থেকে আরও একটি মাপের সমাধান রয়েছে।
ইপোলিনারিও

1
এটি dfকলামের মাল্টি ইনডেক্সগুলির সাথে আমার পক্ষে যথেষ্ট কাজ করে না (এটি প্রথমটি সংশ্লেষের জন্য কাজ করা কলাম হিসাবে 'অন' ইনজেকশন দিচ্ছিল, তবে পরবর্তী সংশ্লেষ ব্যর্থ হয়েছিল), পরিবর্তে আমি এটি নিয়ে কাজ করতে পেরেছি:df = reduce(lambda left, right: left.join(right, how='outer', on='Date'), dfs)
অ্যাড্রিয়ান টেরি

+1 থেকে PS0604। যোগদানের কলামগুলি পৃথক হলে কী কাজ করবে? যোগদানের কলামগুলি আলাদা হলে কী আমরা পিডি.ড্যামার সাথে যেতে পারি? ধন্যবাদ
স্টিভ

106

আপনার কাছে 3 টি ডেটা ফ্রেম থাকলে আপনি এটি চেষ্টা করতে পারেন

# Merge multiple dataframes
df1 = pd.DataFrame(np.array([
    ['a', 5, 9],
    ['b', 4, 61],
    ['c', 24, 9]]),
    columns=['name', 'attr11', 'attr12'])
df2 = pd.DataFrame(np.array([
    ['a', 5, 19],
    ['b', 14, 16],
    ['c', 4, 9]]),
    columns=['name', 'attr21', 'attr22'])
df3 = pd.DataFrame(np.array([
    ['a', 15, 49],
    ['b', 4, 36],
    ['c', 14, 9]]),
    columns=['name', 'attr31', 'attr32'])

pd.merge(pd.merge(df1,df2,on='name'),df3,on='name')

বিকল্পভাবে, cwharland দ্বারা উল্লিখিত হিসাবে

df1.merge(df2,on='name').merge(df3,on='name')

34
ক্লিনার চেহারার জন্য আপনি সেগুলি চেইন করতে পারেন df1.merge(df2,on='name').merge(df3,on='name')
cwharland

1
আমি যুক্ত হতে ক্ষেত্রের নামগুলি পৃথক হলে এই সমাধানটি কীভাবে কাজ করবে? উদাহরণ হিসেবে বলা যায়, তিন ডেটা ফ্রেম আমি থাকতে পারে name1, name2এবং name3যথাক্রমে
ps0604

4
@ PS0604df1.merge(df2,left_on='name1', right_on='name2').merge(df3,left_on='name1', right_on='name3').drop(columns=['name2', 'name3']).rename(columns={'name1':'name'})
মাইকেল এইচ।

এবং আরও, সূচকটি ব্যবহার করে এটি কীভাবে করা যায়। 'নাম' সূচক এবং কোনও কলামের নাম না হলে কাজ করে বলে মনে হচ্ছে না।
ব্রায়ান ডি

85

এটি joinপদ্ধতির জন্য একটি আদর্শ পরিস্থিতি

joinপদ্ধতি ঠিক পরিস্থিতিতে এই ধরনের জন্য নির্মিত হয়। আপনি এর সাথে একসাথে যে কোনও সংখ্যক ডেটাফ্রেমে যোগদান করতে পারেন। কলিং ডেটাফ্রেম পাস হওয়া ডেটা ফ্রেমের সংগ্রহের সূচকের সাথে যোগ দেয়। একাধিক ডাটাফ্রেমে কাজ করার জন্য আপনাকে অবশ্যই যোগদানের কলামগুলি সূচকে রেখে দিতে হবে।

কোডটি এরকম কিছু দেখাচ্ছে:

filenames = ['fn1', 'fn2', 'fn3', 'fn4',....]
dfs = [pd.read_csv(filename, index_col=index_col) for filename in filenames)]
dfs[0].join(dfs[1:])

@ শূন্যের ডেটা সহ, আপনি এটি করতে পারেন:

df1 = pd.DataFrame(np.array([
    ['a', 5, 9],
    ['b', 4, 61],
    ['c', 24, 9]]),
    columns=['name', 'attr11', 'attr12'])
df2 = pd.DataFrame(np.array([
    ['a', 5, 19],
    ['b', 14, 16],
    ['c', 4, 9]]),
    columns=['name', 'attr21', 'attr22'])
df3 = pd.DataFrame(np.array([
    ['a', 15, 49],
    ['b', 4, 36],
    ['c', 14, 9]]),
    columns=['name', 'attr31', 'attr32'])

dfs = [df1, df2, df3]
dfs = [df.set_index('name') for df in dfs]
dfs[0].join(dfs[1:])

     attr11 attr12 attr21 attr22 attr31 attr32
name                                          
a         5      9      5     19     15     49
b         4     61     14     16      4     36
c        24      9      4      9     14      9

4
DFS সব খালি dataframe করার সময় যোগদান কাজ করে: pd.DataFrame().join(dfs, how="outer")। এটি কিছু পরিস্থিতিতে পরিষ্কার হতে পারে।
ডোমিনিক

4
এটি শালীন পরামর্শ এবং এখন 101 মার্জ করা পান্ডায় অন্তর্ভুক্ত করা হয়েছে (একাধিক ডেটাফ্রেমগুলি মার্জ করার অংশটি দেখুন)। এটা তোলে এর মূল্য লক্ষ করেন, যদি আপনার যোগদানের কী অনন্য ব্যবহার pd.concatসহজ সিনট্যাক্স স্থাপিত হবে: pd.concat([df.set_index('name') for df in dfs], axis=1, join='inner').reset_index()concatএকাধিক ডিএফএস জুড়ে সদৃশ কলামের নামগুলির সাথে লেনদেন করার সময় এটি আরও বহুমুখী ( joinযদিও এটি এতটা ভাল নয়) যদিও আপনি কেবল এটির সাথে অভ্যন্তরীণ বা বহিরাগত যোগদান করতে পারেন।
cs95

dfs[0].join(dfs[1:])এডিট করা উচিত dfs[0].join(dfs[1:], sort=False) কারণ অন্যথায় একটি FutureWarningপপ আপ হবে। সুন্দর উদাহরণের জন্য ধন্যবাদ।
gies0r

এটি চেষ্টা করার ক্ষেত্রে আমি একটি ত্রুটি পেয়েছি: ValueError: Indexes have overlapping valuesযদিও তালিকার পৃথক ডেটাফ্রেমগুলি পরিদর্শন করে তাদের ওভারল্যাপিংয়ের মান রয়েছে বলে মনে হয় না।
সোমজুরা

17

এটি ডেটাফ্রেমগুলির তালিকার জন্য নিম্নলিখিত হিসাবেও করা যেতে পারে df_list:

df = df_list[0]
for df_ in df_list[1:]:
    df = df.merge(df_, on='join_col_name')

অথবা যদি ডেটাফ্রেমগুলি কোনও জেনারেটরের অবজেক্টে থাকে (যেমন মেমরির খরচ কমাতে):

df = next(df_list)
for df_ in df_list:
    df = df.merge(df_, on='join_col_name')

11

ইন python3.6.3 সঙ্গে pandas0.22.0 আপনার কাছে ব্যবহার করতে পারেন concatযতদিন না পর্যন্ত আপনি কলাম আপনি যোগ দেওয়ার জন্য ব্যবহার করতে চান সূচক হিসাবে সেট হিসাবে

pd.concat(
    (iDF.set_index('name') for iDF in [df1, df2, df3]),
    axis=1, join='inner'
).reset_index()

যেখানে df1, df2এবং df3হিসাবে সংজ্ঞায়িত করা হয় জন Galt এর উত্তর

import pandas as pd
df1 = pd.DataFrame(np.array([
    ['a', 5, 9],
    ['b', 4, 61],
    ['c', 24, 9]]),
    columns=['name', 'attr11', 'attr12']
)
df2 = pd.DataFrame(np.array([
    ['a', 5, 19],
    ['b', 14, 16],
    ['c', 4, 9]]),
    columns=['name', 'attr21', 'attr22']
)
df3 = pd.DataFrame(np.array([
    ['a', 15, 49],
    ['b', 4, 36],
    ['c', 14, 9]]),
    columns=['name', 'attr31', 'attr32']
)

2
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এটি দ্রুততম।
আর ঝু

4

যোগদানের ক্রিয়াকলাপ সম্পাদনের জন্য একটির জন্য একটি মাল্টিইন্ডেক্সের প্রয়োজন নেই । একটিতে সঠিকভাবে ইনডেক্স কলাম সেট করতে হবে যার উপর যোগদানের ক্রিয়াকলাপ সম্পাদন করতে হবে ( df.set_index('Name')উদাহরণস্বরূপ কোন আদেশ )

joinঅপারেশন সূচক সম্পাদনা ডিফল্ট দ্বারা হয়। আপনার ক্ষেত্রে, আপনাকে কেবল নির্দিষ্ট করতে হবে যে Nameকলামটি আপনার সূচকের সাথে সম্পর্কিত। নীচে একটি উদাহরণ দেওয়া আছে

একটি টিউটোরিয়াল দরকারী হতে পারে।

# Simple example where dataframes index are the name on which to perform the join operations
import pandas as pd
import numpy as np
name = ['Sophia' ,'Emma' ,'Isabella' ,'Olivia' ,'Ava' ,'Emily' ,'Abigail' ,'Mia']
df1 = pd.DataFrame(np.random.randn(8, 3), columns=['A','B','C'], index=name)
df2 = pd.DataFrame(np.random.randn(8, 1), columns=['D'],         index=name)
df3 = pd.DataFrame(np.random.randn(8, 2), columns=['E','F'],     index=name)
df = df1.join(df2)
df = df.join(df3)

# If you a 'Name' column that is not the index of your dataframe, one can set this column to be the index
# 1) Create a column 'Name' based on the previous index
df1['Name']=df1.index
# 1) Select the index from column 'Name'
df1=df1.set_index('Name')

# If indexes are different, one may have to play with parameter how
gf1 = pd.DataFrame(np.random.randn(8, 3), columns=['A','B','C'], index=range(8))
gf2 = pd.DataFrame(np.random.randn(8, 1), columns=['D'], index=range(2,10))
gf3 = pd.DataFrame(np.random.randn(8, 2), columns=['E','F'], index=range(4,12))

gf = gf1.join(gf2, how='outer')
gf = gf.join(gf3, how='outer')

4

অভিধানের সাথে সিঙ্কে কলামের নাম রাখার সময় এখানে ডেটা ফ্রেমের একটি অভিধান মার্জ করার একটি পদ্ধতি রয়েছে। প্রয়োজনে এটি অনুপস্থিত মানগুলিতে পূরণ করে:

এটি ডেটা ফ্রেমের ডিক্ট মার্জ করার ফাংশন

def MergeDfDict(dfDict, onCols, how='outer', naFill=None):
  keys = dfDict.keys()
  for i in range(len(keys)):
    key = keys[i]
    df0 = dfDict[key]
    cols = list(df0.columns)
    valueCols = list(filter(lambda x: x not in (onCols), cols))
    df0 = df0[onCols + valueCols]
    df0.columns = onCols + [(s + '_' + key) for s in valueCols] 

    if (i == 0):
      outDf = df0
    else:
      outDf = pd.merge(outDf, df0, how=how, on=onCols)   

  if (naFill != None):
    outDf = outDf.fillna(naFill)

  return(outDf)

ঠিক আছে, ডেটা উত্পন্ন এবং এটি পরীক্ষা করতে দেয়:

def GenDf(size):
  df = pd.DataFrame({'categ1':np.random.choice(a=['a', 'b', 'c', 'd', 'e'], size=size, replace=True),
                      'categ2':np.random.choice(a=['A', 'B'], size=size, replace=True), 
                      'col1':np.random.uniform(low=0.0, high=100.0, size=size), 
                      'col2':np.random.uniform(low=0.0, high=100.0, size=size)
                      })
  df = df.sort_values(['categ2', 'categ1', 'col1', 'col2'])
  return(df)


size = 5
dfDict = {'US':GenDf(size), 'IN':GenDf(size), 'GER':GenDf(size)}   
MergeDfDict(dfDict=dfDict, onCols=['categ1', 'categ2'], how='outer', naFill=0)

3

সহজ সমাধান:

যদি কলামের নাম একই হয়:

 df1.merge(df2,on='col_name').merge(df3,on='col_name')

কলামের নামগুলি পৃথক হলে:

df1.merge(df2,left_on='col_name1', right_on='col_name2').merge(df3,left_on='col_name1', right_on='col_name3').drop(columns=['col_name2', 'col_name3']).rename(columns={'col_name1':'col_name'})

2

পান্ডাস ডকুমেন্টেশন থেকে অন্য সমাধান রয়েছে (যা আমি এখানে দেখি না),

ব্যবহার করে .append

>>> df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
   A  B
0  1  2
1  3  4
>>> df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))
   A  B
0  5  6
1  7  8
>>> df.append(df2, ignore_index=True)
   A  B
0  1  2
1  3  4
2  5  6
3  7  8

ignore_index=True, যোগ dataframe সূচী উপেক্ষা করার উৎস এক পাওয়া পরবর্তী সূচক সঙ্গে এটি প্রতিস্থাপন ব্যবহার করা হয়।

যদি বিভিন্ন কলামের নাম থাকে Nanতবে পরিচয় করানো হবে।


এটি শব্দার্থক, কেউ কেউ "যুক্ত" শব্দটি ব্যবহার করে দুটি ডাটাফ্রেম একসাথে রাখার জন্য বলে। (এসকিউএল যোগদানের অপারেশন হিসাবে অগত্যা নয়)
সিলেহর

1

তিনটি ডাটাফ্রেম হ'ল

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

নেস্টেড পিডি.মার্জ ব্যবহার করে এই ফ্রেমগুলি মার্জ করুন

এখানে চিত্র বর্ণনা লিখুন

আমরা এখানে যাই, আমাদের একীভূত ডেটাফ্রেম রয়েছে।

শুভ বিশ্লেষণ !!!

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