পান্ডস একাধিক কলামে তালিকার কলাম বিভক্ত করুন


135

আমার একটি কলাম সহ একটি পান্ডাস ডেটা ফ্রেম রয়েছে:

import pandas as pd

df = pd.DataFrame(
    data={
        "teams": [
            ["SF", "NYG"],
            ["SF", "NYG"],
            ["SF", "NYG"],
            ["SF", "NYG"],
            ["SF", "NYG"],
            ["SF", "NYG"],
            ["SF", "NYG"],
        ]
    }
)

print(df)

আউটপুট:

       teams
0  [SF, NYG]
1  [SF, NYG]
2  [SF, NYG]
3  [SF, NYG]
4  [SF, NYG]
5  [SF, NYG]
6  [SF, NYG]

তালিকার এই কলামটি কীভাবে 2 টি কলামে বিভক্ত করা যায়?

উত্তর:


243

আপনি এর দ্বারা নির্মিত দ্বারা DataFrameনির্মাণকারী ব্যবহার করতে পারেন :liststo_list

import pandas as pd

d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
                ['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
print (df2)
       teams
0  [SF, NYG]
1  [SF, NYG]
2  [SF, NYG]
3  [SF, NYG]
4  [SF, NYG]
5  [SF, NYG]
6  [SF, NYG]

df2[['team1','team2']] = pd.DataFrame(df2.teams.tolist(), index= df2.index)
print (df2)
       teams team1 team2
0  [SF, NYG]    SF   NYG
1  [SF, NYG]    SF   NYG
2  [SF, NYG]    SF   NYG
3  [SF, NYG]    SF   NYG
4  [SF, NYG]    SF   NYG
5  [SF, NYG]    SF   NYG
6  [SF, NYG]    SF   NYG

এবং নতুন জন্য DataFrame:

df3 = pd.DataFrame(df2['teams'].to_list(), columns=['team1','team2'])
print (df3)
  team1 team2
0    SF   NYG
1    SF   NYG
2    SF   NYG
3    SF   NYG
4    SF   NYG
5    SF   NYG
6    SF   NYG

এর সাথে সমাধান apply(pd.Series)খুব ধীর:

#7k rows
df2 = pd.concat([df2]*1000).reset_index(drop=True)

In [121]: %timeit df2['teams'].apply(pd.Series)
1.79 s ± 52.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [122]: %timeit pd.DataFrame(df2['teams'].to_list(), columns=['team1','team2'])
1.63 ms ± 54.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

4
মাইনর ক্যাভেট, আপনি যদি এটি বিদ্যমান ডেটাফ্রেমে ব্যবহার করে থাকেন তবে সূচীটি পুনরায় সেট করতে ভুলবেন না অন্যথায় এটি সঠিকভাবে বরাদ্দ করবে না।
ব্যবহারকারী 1700890

1
@ ব্যবহারকারী 1700890 - হ্যাঁ, বা ডেটাফ্রেম কনস্ট্রাক্টরে সূচি নির্দিষ্ট করুনdf2[['team1','team2']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)
জিজরেল

1
@ গুটিবিল্টস - হ্যাঁ, যদি ভেক্টরাইজ সলিউশন উপস্থিত থাকে তবে এটি এড়ানো ভাল।
jezrael

1
@ গুটিবিল্টস - হ্যাঁ, স্পষ্টতই। ভেক্টরাইজড অর্থ সাধারণত লুপ হয় না, সুতরাং প্রয়োগ করা হয় না, কোনও তালিকার বোধগম্যতা নেই। তবে এটি নির্ভর করে ঠিক কী প্রয়োজন। সম্ভবত
এটিতেও

2
@ গুগলবিল্টস প্রকৃতপক্ষে apply()ধীর হতে পারে তবে মূল সিরিজের সারিগুলিতে ইনপুট স্ট্রিং এবং মানগুলি সমান হয় না এমনটাই চলার পদ্ধতি!
চেটেস্তা

52

অনেক সহজ সমাধান:

pd.DataFrame(df2["teams"].to_list(), columns=['team1', 'team2'])

উৎপাদনের,

  team1 team2
-------------
0    SF   NYG
1    SF   NYG
2    SF   NYG
3    SF   NYG
4    SF   NYG
5    SF   NYG
6    SF   NYG
7    SF   NYG

আপনি যদি তালিকার পরিবর্তে সীমিত স্ট্রিংগুলির একটি কলাম বিভক্ত করতে চান, আপনি একইভাবে করতে পারেন:

pd.DataFrame(df["teams"].str.split('<delim>', expand=True).values,
             columns=['team1', 'team2'])

6
প্রতিটি তালিকায় যদি অসম সংখ্যক উপাদান থাকে?
ইকেল

আপনি যদি তালিকার পরিবর্তে ডিলিমিটেড স্ট্রিংগুলির একটি কলাম বিভক্ত করতে চান, আপনি একইভাবে করতে পারেন: df["teams"].str.split('<delim>', expand=True) ইতিমধ্যে একটি ডেটা ফ্রেম প্রদান করে, তাই কেবল কলামগুলির নাম পরিবর্তন করা সহজতর হবে।
এএমসি

26

এই সমাধানটি df2ডেটাফ্রেমের সূচি সংরক্ষণ করে , যে কোনও সমাধান ব্যবহার করে tolist():

df3 = df2.teams.apply(pd.Series)
df3.columns = ['team1', 'team2']

ফলাফল এখানে:

  team1 team2
0    SF   NYG
1    SF   NYG
2    SF   NYG
3    SF   NYG
4    SF   NYG
5    SF   NYG
6    SF   NYG

2
এছাড়াও পান্ডায় applyআপনি সবচেয়ে ধীর করতে পারেন। আপনার এই পদ্ধতিটি এড়ানো উচিত এবং স্বীকৃত উত্তরটি ব্যবহার করা উচিত। শীর্ষ উত্তরের সময়, এই পদ্ধতিটি প্রায় 1400 xধীরে @rajan
এরফান

2
@ ইরফান হ্যাঁ, তবে কখনও কখনও ব্যবহারকারী কোনও অপারেশনটি 1s বা 1 মিমি নেয় কিনা তা বিবেচনা করে না এবং এর পরিবর্তে তারা সহজতম, সর্বাধিক পঠনযোগ্য কোড লেখার বিষয়ে সবচেয়ে বেশি যত্ন করে! আমি স্বীকার করি যে পাঠযোগ্যতা / সরলতা বিষয়বস্তু, তবে আমার বক্তব্যটি হ'ল গতি সব সময়ে সমস্ত ব্যবহারকারীর পক্ষে অগ্রাধিকার নয়।
কেভিন মার্কহাম

1
তদুপরি, আমি জানতে পেরেছি যে applyপদ্ধতিটি বড় ডেটার সেটগুলিতে বড় অ্যারে (1000+ আইটেম) প্রসারণের জন্য আরও নির্ভরযোগ্যতার সাথে কাজ করে। tolist()পদ্ধতি আমার প্রক্রিয়া নষ্ট হয়েছে যখন ডেটা সেট 500K সারি ছাড়িয়ে গেছে।
মরিৎজ

2
এটি একটি দুর্দান্ত সমাধান কারণ এটি বিভিন্ন আকারের তালিকার সাথে ভাল কাজ করে।
দাসিলভাদানীয়েল

@ কেভিনমারখাম তারা সবচেয়ে সরল, সর্বাধিক পঠনযোগ্য কোড লেখার বিষয়ে সবচেয়ে বেশি যত্নশীলpd.DataFrame(df["teams"].to_list(), columns=["team_1", "team_2"]) সত্যই কি আরও জটিল?
এএমসি

15

প্রস্তাবিত সমাধানগুলির বিপরীতে একটি সিন্ট্যাক্টিক্যালি সহজ উপায় বলে মনে হয় এবং তাই সহজেই মনে রাখা সহজ। আমি ধরে নিচ্ছি যে কলামটি ডেটাফ্রেম ডিএফ-তে 'মেটা' নামে পরিচিত:

df2 = pd.DataFrame(df['meta'].str.split().values.tolist())

1
আমি একটি ত্রুটি পেয়েছি কিন্তু আমি এটি সরিয়ে সমাধান করেছি str.split()। এটি অনেক সহজ ছিল এবং আপনি যদি আপনার তালিকার আইটেমগুলির সংখ্যা জানেন না তবে সুবিধাও রয়েছে।
ওটিতেং

প্রস্তাবিত সমাধানগুলির বিপরীতে একটি সিন্ট্যাক্টিক্যালি সহজ উপায় বলে মনে হয় এবং তাই সহজেই মনে রাখা সহজ। সত্যি? কারণ এটি বেশিরভাগ বছর আগে পোস্ট করা শীর্ষের উত্তরের সাথে কার্যত অভিন্ন। পার্থক্য কেবলমাত্র সেই অংশটি যা এই নির্দিষ্ট প্রশ্নের সাথে সম্পর্কিত নয়।
এএমসি

এটা আমার কাজ করে !!
এডুয়ার্ডো ওস্তারেজ

3

পূর্ববর্তী উত্তরের উপর ভিত্তি করে, এখানে আরও একটি সমাধান দেওয়া হয়েছে যা df2.teams.apply (pd.Series) হিসাবে একই দ্রুত ফলাফলের সাথে একই ফলাফল দেয়:

pd.DataFrame([{x: y for x, y in enumerate(item)} for item in df2['teams'].values.tolist()], index=df2.index)

সময়:

In [1]:
import pandas as pd
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
                ['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
df2 = pd.concat([df2]*1000).reset_index(drop=True)

In [2]: %timeit df2['teams'].apply(pd.Series)

8.27 s ± 2.73 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [3]: %timeit pd.DataFrame([{x: y for x, y in enumerate(item)} for item in df2['teams'].values.tolist()], index=df2.index)

35.4 ms ± 5.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

3

উপরের সমাধানগুলি আমার পক্ষে কার্যকর হয়নি যেহেতু আমার nanআমার পর্যবেক্ষণ রয়েছে dataframe। আমার ক্ষেত্রে df2[['team1','team2']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)ফলন:

object of type 'float' has no len()

আমি তালিকা বোধগম্যতা ব্যবহার করে এটি সমাধান করি। এখানে প্রতিরূপ উদাহরণ:

import pandas as pd
import numpy as np
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
            ['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
df2.loc[2,'teams'] = np.nan
df2.loc[4,'teams'] = np.nan
df2

আউটপুট:

        teams
0   [SF, NYG]
1   [SF, NYG]
2   NaN
3   [SF, NYG]
4   NaN
5   [SF, NYG]
6   [SF, NYG]

df2['team1']=np.nan
df2['team2']=np.nan

তালিকা বোঝার সাথে সমাধান:

for i in [0,1]:
    df2['team{}'.format(str(i+1))]=[k[i] if isinstance(k,list) else k for k in df2['teams']]

df2

উৎপাদনের:

    teams   team1   team2
0   [SF, NYG]   SF  NYG
1   [SF, NYG]   SF  NYG
2   NaN        NaN  NaN
3   [SF, NYG]   SF  NYG
4   NaN        NaN  NaN
5   [SF, NYG]   SF  NYG
6   [SF, NYG]   SF  NYG

1

তালিকা উপলব্ধি

তালিকা বোঝার সাথে সহজ বাস্তবায়ন (আমার প্রিয়)

df = pd.DataFrame([pd.Series(x) for x in df.teams])
df.columns = ['team_{}'.format(x+1) for x in df.columns]

আউটপুট সময়:

CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 2.71 ms

আউটপুট:

team_1  team_2
0   SF  NYG
1   SF  NYG
2   SF  NYG
3   SF  NYG
4   SF  NYG
5   SF  NYG
6   SF  NYG

এই ধরণের বিভিন্ন দৈর্ঘ্যের তালিকা পরিচালনা করে - যা অন্যান্য অনেক উত্তরের তুলনায় উন্নতি, তবে আইটেমগুলি তাদের নিজস্ব কলামে না থাকার ফলস্বরূপ।
আইজাক

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