পান্ডাস ডাটাফ্রেমে টিপলসের কলাম কীভাবে বিভক্ত করবেন?


91

আমার কাছে একটি পান্ডাস ডেটা ফ্রেম রয়েছে (এটি কেবল সামান্য টুকরো)

>>> d1
   y norm test  y norm train  len(y_train)  len(y_test)  \
0    64.904368    116.151232          1645          549   
1    70.852681    112.639876          1645          549   

                                    SVR RBF  \
0   (35.652207342877873, 22.95533537448393)   
1  (39.563683797747622, 27.382483096332511)   

                                        LCV  \
0  (19.365430594452338, 13.880062435173587)   
1  (19.099614489458364, 14.018867136617146)   

                                   RIDGE CV  \
0  (4.2907610988480362, 12.416745648065584)   
1    (4.18864306788194, 12.980833914392477)   

                                         RF  \
0   (9.9484841581029428, 16.46902345373697)   
1  (10.139848213735391, 16.282141345406522)   

                                           GB  \
0  (0.012816232716538605, 15.950164822266007)   
1  (0.012814519804493328, 15.305745202851712)   

                                             ET DATA  
0  (0.00034337162272515505, 16.284800366214057)  j2m  
1  (0.00024811554516431878, 15.556506191784194)  j2m  
>>> 

আমি সমস্ত কলামগুলিকে বিভক্ত করতে চাই যেখানে টিপলস রয়েছে। উদাহরণস্বরূপ আমি LCVকলামগুলি কলাম LCV-aএবং এর সাথে প্রতিস্থাপন করতে চাই LCV-b

আমি এটা কিভাবে করবো?

উত্তর:


167

আপনি এই pd.DataFrame(col.tolist())কলামটি করে এটি করতে পারেন :

In [2]: df = pd.DataFrame({'a':[1,2], 'b':[(1,2), (3,4)]})                                                                                                                      

In [3]: df                                                                                                                                                                      
Out[3]: 
   a       b
0  1  (1, 2)
1  2  (3, 4)

In [4]: df['b'].tolist()                                                                                                                                                        
Out[4]: [(1, 2), (3, 4)]

In [5]: pd.DataFrame(df['b'].tolist(), index=df.index)                                                                                                                                          
Out[5]: 
   0  1
0  1  2
1  3  4

In [6]: df[['b1', 'b2']] = pd.DataFrame(df['b'].tolist(), index=df.index)                                                                                                                       

In [7]: df                                                                                                                                                                      
Out[7]: 
   a       b  b1  b2
0  1  (1, 2)   1   2
1  2  (3, 4)   3   4

দ্রষ্টব্য: পূর্ববর্তী সংস্করণে, এই উত্তরটি df['b'].apply(pd.Series)পরিবর্তে ব্যবহারের জন্য প্রস্তাবিত pd.DataFrame(df['b'].tolist(), index=df.index)। এটি পাশাপাশি কাজ করে (কারণ এটি প্রতিটি টিপলকে একটি সিরিজ তৈরি করে, যা পরে ডেটাফ্রেমের সারি হিসাবে দেখা হয়) তবে tolistঅন্যান্য উত্তর দ্বারা উল্লিখিত হিসাবে এটি ধীর / সংস্করণটির চেয়ে বেশি মেমরি ব্যবহার করে (@ এডফ্রুমুফাকে ধন্যবাদ) ।
সর্বাধিক দৃশ্যমান উত্তরের সর্বোত্তম সমাধান রয়েছে তা নিশ্চিত করতে আমি এই উত্তরটি আপডেট করেছি।


4
বিপুল সংখ্যক কলামের কারণে এটি স্বয়ংক্রিয় করার কোনও উপায় আছে?
ডোনবিও

সরাসরি না ভাবি। তবে আপনি উপরের কোডটি ব্যবহার করে সহজেই এর জন্য একটি ফাংশন লিখতে পারেন (+ মূলটি মুছে
ফেলছেন

আপনার যদি প্রচুর পরিমাণে কলাম থাকে তবে আপনি আপনার ডেটাটি 'পরিষ্কার' করতে বিবেচনা করতে পারেন: vita.had.co.nz/papers/tidy-data.html আপনি গলিত ফাংশনটি ব্যবহার করে এটি করতে পারেন।
এক্সেল

। অ্যাপ্লিকেশন (পিডি। সিরিজ) সূক্ষ্মভাবে কাজ করে, তবে বড় ডেটাসেটগুলির জন্য প্রচুর স্মৃতি গ্রহণ করে এবং মেমোরি ত্রুটির কারণ হতে পারে
ইউরি ওয়ালেট

27

অনেক বড় ডেটাসেটে, আমি এটি পেয়েছি .apply() চেয়ে কম অর্ডার কমpd.DataFrame(df['b'].values.tolist(), index=df.index)

এই পারফরম্যান্স ইস্যুটি গিটহাবে বন্ধ ছিল, যদিও আমি এই সিদ্ধান্তের সাথে একমত নই:

https://github.com/pandas-dev/pandas/issues/11615

সম্পাদনা: এই উত্তরের উপর ভিত্তি করে: https://stackoverflow.com/a/44196843/2230844


4
pd.DataFrame(df['b'].tolist())ছাড়া .valuesশুধু জরিমানা খুব কাজ মনে হয়। (এবং ধন্যবাদ, আপনার সমাধান এর চেয়ে অনেক দ্রুত .apply())
সুইয়ার

আমি সূচক ক্যাপচার সম্পর্কে উদ্বিগ্ন ছিলাম, তাই। মূল্যগুলির সুস্পষ্ট ব্যবহার।
denfromufa

4
@denfromufa দ্বারা সমাধান সুপার দ্রুত কাজ করে df [['b1', 'b2']] = পিডি.ডাটা ফ্রেম (ডিএফ ['বি']। মান.টোলিস্ট (), সূচক = df.index) এবং কোনও স্মৃতি ত্রুটির কারণ হিসাবে নেই (হিসাবে অ্যাপ্লিকেশন (পিডি। সিরিজ) এর সাথে তুলনা করুন
ইউরি ওয়ালেট

22

যে strঅ্যাক্সেসরের pandas.Seriesবস্তুর জন্য উপলব্ধ dtype == objectতা আসলে একটি পুনরাবৃত্ত।

ধরুন pandas.DataFrame df:

df = pd.DataFrame(dict(col=[*zip('abcdefghij', range(10, 101, 10))]))

df

        col
0   (a, 10)
1   (b, 20)
2   (c, 30)
3   (d, 40)
4   (e, 50)
5   (f, 60)
6   (g, 70)
7   (h, 80)
8   (i, 90)
9  (j, 100)

এটি যদি পুনরাবৃত্তিযোগ্য হয় তবে আমরা পরীক্ষা করতে পারি

from collections import Iterable

isinstance(df.col.str, Iterable)

True

এরপরে আমরা অন্যটি পুনরাবৃত্ত করার মতো করে এর থেকে নির্ধারণ করতে পারি:

var0, var1 = 'xy'
print(var0, var1)

x y

সহজ সমাধান

সুতরাং এক লাইনে আমরা উভয় কলাম নির্ধারণ করতে পারি

df['a'], df['b'] = df.col.str

df

        col  a    b
0   (a, 10)  a   10
1   (b, 20)  b   20
2   (c, 30)  c   30
3   (d, 40)  d   40
4   (e, 50)  e   50
5   (f, 60)  f   60
6   (g, 70)  g   70
7   (h, 80)  h   80
8   (i, 90)  i   90
9  (j, 100)  j  100

দ্রুত সমাধান

কেবল কিছুটা আরও জটিল, আমরা zipএকই ধরণের পুনরাবৃত্তি তৈরি করতে ব্যবহার করতে পারি

df['c'], df['d'] = zip(*df.col)

df

        col  a    b  c    d
0   (a, 10)  a   10  a   10
1   (b, 20)  b   20  b   20
2   (c, 30)  c   30  c   30
3   (d, 40)  d   40  d   40
4   (e, 50)  e   50  e   50
5   (f, 60)  f   60  f   60
6   (g, 70)  g   70  g   70
7   (h, 80)  h   80  h   80
8   (i, 90)  i   90  i   90
9  (j, 100)  j  100  j  100

সারিতে

অর্থ, বিদ্যমান রূপান্তর করবেন না df
এটি কাজ করে কারণ মূলশব্দটি assignনতুন (বা বিদ্যমান) কলামের নাম এবং মানগুলি নতুন কলামের মান হবে key আপনি একটি অভিধান ব্যবহার করতে পারেন এবং এটি আনপ্যাক করতে **এবং এটি কীওয়ার্ড আর্গুমেন্ট হিসাবে কাজ করতে পারেন । সুতরাং এটি একটি নতুন কলামের নামকরণের একটি চতুর উপায় 'g'যা df.col.strপুনরাবৃত্তির প্রথম আইটেম এবং এটি পুনরাবৃত্তির 'h'দ্বিতীয় আইটেম df.col.str

df.assign(**dict(zip('gh', df.col.str)))

        col  g    h
0   (a, 10)  a   10
1   (b, 20)  b   20
2   (c, 30)  c   30
3   (d, 40)  d   40
4   (e, 50)  e   50
5   (f, 60)  f   60
6   (g, 70)  g   70
7   (h, 80)  h   80
8   (i, 90)  i   90
9  (j, 100)  j  100

আমার সংস্করণ list পদ্ধতির

আধুনিক তালিকা অনুধাবন এবং পরিবর্তনশীল আনপ্যাকিং সহ With
দ্রষ্টব্য: এছাড়াও ইনলাইন ব্যবহারjoin

df.join(pd.DataFrame([*df.col], df.index, [*'ef']))

        col  g    h
0   (a, 10)  a   10
1   (b, 20)  b   20
2   (c, 30)  c   30
3   (d, 40)  d   40
4   (e, 50)  e   50
5   (f, 60)  f   60
6   (g, 70)  g   70
7   (h, 80)  h   80
8   (i, 90)  i   90
9  (j, 100)  j  100

পরিবর্তিত সংস্করণ হবে

df[['e', 'f']] = pd.DataFrame([*df.col], df.index)

নিষ্পাপ সময় পরীক্ষা

সংক্ষিপ্ত ডাটাফ্রেম

উপরে বর্ণিত একটি ব্যবহার করুন

%timeit df.assign(**dict(zip('gh', df.col.str)))
%timeit df.assign(**dict(zip('gh', zip(*df.col))))
%timeit df.join(pd.DataFrame([*df.col], df.index, [*'gh']))

1.16 ms ± 21.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
635 µs ± 18.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
795 µs ± 42.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
দীর্ঘ ডেটাফ্রেম

10 ^ 3 গুণ বড়

df = pd.concat([df] * 1000, ignore_index=True)

%timeit df.assign(**dict(zip('gh', df.col.str)))
%timeit df.assign(**dict(zip('gh', zip(*df.col))))
%timeit df.join(pd.DataFrame([*df.col], df.index, [*'gh']))

11.4 ms ± 1.53 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.1 ms ± 41.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.33 ms ± 35.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

4
টিএল যোগ করার কথা বিবেচনা করুন; ডিআর: df['a'], df['b'] = df.col.str:)
মাইরেকএফডি

11

আমি মনে করি একটি সহজ উপায় হ'ল:

>>> import pandas as pd
>>> df = pd.DataFrame({'a':[1,2], 'b':[(1,2), (3,4)]}) 
>>> df
   a       b
0  1  (1, 2)
1  2  (3, 4)
>>> df['b_a']=df['b'].str[0]
>>> df['b_b']=df['b'].str[1]
>>> df
   a       b  b_a  b_b
0  1  (1, 2)    1    2
1  2  (3, 4)    3    4

4
এই সমাধানগুলি সত্যই অনেক বেশি সহজ
অ্যাপলপি

@ জিনহুয়াং এটি প্রদর্শিত হচ্ছে এটি strকোনও pd.Seriesবস্তুর উপস্থাপনের শীর্ষে হ্যাক । এটি কীভাবে কাজ করে তা ব্যাখ্যা করতে পারেন?!
denfromufa

আমি মনে করি এটি ঠিক কীভাবে স্ট্রিং অবজেক্টটি কাজ করে? আপনি
জিনুয়া ওয়াং

সারিগুলির কয়েকটিতে যদি বিভিন্ন সংখ্যার মান নিয়ে টিপল থাকে তবে কী হবে?
mammykins

আমি মনে করি এটি গ্রহণযোগ্য হওয়া উচিত। এটি আরও 'পান্ডাস-ওনিক' ... যদি এটি কোনও জিনিস হয়।
নাতাচা

8

আমি জানি এটি কিছুকাল আগে থেকেই, তবে দ্বিতীয় সমাধানের একটি সতর্কতা:

pd.DataFrame(df['b'].values.tolist())

এটি হ'ল এটি স্পষ্টভাবে সূচকটি বাতিল করে দেবে এবং একটি ডিফল্ট অনুক্রমিক সূচক যুক্ত করবে, যেখানে গৃহীত উত্তর

apply(pd.Series)

হবে না, যেহেতু প্রয়োগের ফলাফলটি সারি সূচককে ধরে রাখবে। অর্ডার প্রাথমিকভাবে মূল অ্যারে থেকে ধরে রাখা হলেও, পান্ডাস দুটি ডাটাফ্রেম থেকে সূচকগুলি মেলানোর চেষ্টা করবেন।

এটি সর্বাধিক গুরুত্বপূর্ণ হতে পারে যদি আপনি সারিগুলিকে একটি সংখ্যা অনুযায়ী সূচিকৃত অ্যারে হিসাবে সেট করার চেষ্টা করছেন এবং পান্ডগুলি স্বয়ংক্রিয়ভাবে নতুন অ্যারের সূচকে পুরানো সাথে মিলিয়ে দেখার চেষ্টা করবে এবং ক্রমটিতে কিছুটা বিকৃতি ঘটায়।

একটি আরও উন্নত সংকর সমাধান হ'ল মূল ডাটাফ্রেমের সূচকে নতুনের উপর সেট করা, অর্থাৎ

pd.DataFrame(df['b'].values.tolist(), index=df.index)

ক্রমটি নিশ্চিত করার সময় দ্বিতীয় পদ্ধতিটি ব্যবহারের গতি বজায় রাখবে এবং ফলাফলের উপরে সূচি বজায় থাকবে।


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