একাধিক ডেটা ফ্রেমে ডেটাফ্রেমকে বিভক্ত করা


92

আমার কাছে একটি পরীক্ষার (respond০ জন উত্তরদাতাদের) ডেটা সহ একটি বিশাল ডেটাফ্রেম (প্রায় 1 মিলিয়ন সারি) রয়েছে।

আমি ডেটাফ্রেমকে 60 ডেটাফ্রেমে বিভক্ত করতে চাই (প্রতিটি অংশগ্রহণকারীর জন্য একটি ডেটা ফ্রেম)।

ডেটাফ্রেমে, dataএখানে একটি ভেরিয়েবল বলা হয় 'name', যা প্রতিটি অংশগ্রহণকারীর জন্য অনন্য কোড।

আমি নিম্নলিখিতগুলি চেষ্টা করে দেখেছি, তবে কিছুই হয় না (বা কার্যকর করা এক ঘন্টার মধ্যে থামবে না)। আমি যা করতে চাই তা হ'ল dataছোট ছোট ডেটাফ্রেমে বিভক্ত করা এবং এগুলি একটি তালিকায় যুক্ত করুন ( datalist):

import pandas as pd

def splitframe(data, name='name'):
    
    n = data[name][0]

    df = pd.DataFrame(columns=data.columns)

    datalist = []

    for i in range(len(data)):
        if data[name][i] == n:
            df = df.append(data.iloc[i])
        else:
            datalist.append(df)
            df = pd.DataFrame(columns=data.columns)
            n = data[name][i]
            df = df.append(data.iloc[i])
        
    return datalist

আমি কোনও ত্রুটি বার্তা পাই না, স্ক্রিপ্টটি কেবল চিরকালের জন্য চলবে বলে মনে হচ্ছে!

এটি করার কোনও স্মার্ট উপায় আছে?

উত্তর:


53

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

যাইহোক, আমি মনে করি আপনার মৌলিকভাবে আপনার দৃষ্টিভঙ্গিটি কিছুটা অপব্যয় কারণ আপনার ইতিমধ্যে ডেটাফ্রেম রয়েছে তাই কেন এই ব্যবহারকারীর প্রত্যেকের জন্য একটি নতুন তৈরি করবেন?

আমি কলাম অনুসারে ডেটাফ্রেমকে বাছাই করব, সূচকে এটিতে 'name'সেট করুন এবং প্রয়োজনে কলামটি না ফেলে।

তারপরে সমস্ত অনন্য এন্ট্রিগুলির একটি তালিকা তৈরি করুন এবং তারপরে আপনি এই এন্ট্রিগুলি ব্যবহার করে একটি অনুসন্ধান সম্পাদন করতে পারবেন এবং গুরুত্বপূর্ণভাবে যদি আপনি কেবল ডেটা অনুসন্ধান করেন, ব্যয়বহুল ডেটা অনুলিপি ব্যতীত ডেটাফ্রেমে কোনও ভিউ ফিরিয়ে দেওয়ার জন্য নির্বাচনের মানদণ্ডটি ব্যবহার করুন।

ব্যবহার করুন pandas.DataFrame.sort_valuesএবং pandas.DataFrame.set_index:

# sort the dataframe
df.sort_values(by='name', axis=1, inplace=True)

# set the index to be this and don't drop
df.set_index(keys=['name'], drop=False,inplace=True)

# get a list of names
names=df['name'].unique().tolist()

# now we can perform a lookup on a 'view' of the dataframe
joe = df.loc[df.name=='joe']

# now you can query all 'joes'

74

আমি কি কেবল ডেটা ফ্রেমের টুকরো টুকরো করে এটি করতে পারি না তা জানতে পারি। কিছুটা এইরকম

#create some data with Names column
data = pd.DataFrame({'Names': ['Joe', 'John', 'Jasper', 'Jez'] *4, 'Ob1' : np.random.rand(16), 'Ob2' : np.random.rand(16)})

#create unique list of names
UniqueNames = data.Names.unique()

#create a data frame dictionary to store your data frames
DataFrameDict = {elem : pd.DataFrame for elem in UniqueNames}

for key in DataFrameDict.keys():
    DataFrameDict[key] = data[:][data.Names == key]

আরে প্রস্টো আপনার কাছে ডেটা ফ্রেমের একটি অভিধান রয়েছে ঠিক যেমন (আমার মনে হয়) আপনি সেগুলি চান। একটি অ্যাক্সেস প্রয়োজন? শুধু প্রবেশ করুন

DataFrameDict['Joe']

আশা করি এইটি কাজ করবে


38

আপনি groupbyঅবজেক্টে tuplesএবং তারপরে রূপান্তর করতে পারেন dict:

df = pd.DataFrame({'Name':list('aabbef'),
                   'A':[4,5,4,5,5,4],
                   'B':[7,8,9,4,2,3],
                   'C':[1,3,5,7,1,0]}, columns = ['Name','A','B','C'])

print (df)
  Name  A  B  C
0    a  4  7  1
1    a  5  8  3
2    b  4  9  5
3    b  5  4  7
4    e  5  2  1
5    f  4  3  0

d = dict(tuple(df.groupby('Name')))
print (d)
{'b':   Name  A  B  C
2    b  4  9  5
3    b  5  4  7, 'e':   Name  A  B  C
4    e  5  2  1, 'a':   Name  A  B  C
0    a  4  7  1
1    a  5  8  3, 'f':   Name  A  B  C
5    f  4  3  0}

print (d['a'])
  Name  A  B  C
0    a  4  7  1
1    a  5  8  3

এটি প্রস্তাবিত নয় , তবে গোষ্ঠীগুলির দ্বারা ডেটা ফ্রেমগুলি তৈরি করা সম্ভব:

for i, g in df.groupby('Name'):
    globals()['df_' + str(i)] =  g

print (df_a)
  Name  A  B  C
0    a  4  7  1
1    a  5  8  3


16

গ্রুপবাই আপনাকে সহায়তা করতে পারে:

grouped = data.groupby(['name'])

তারপরে আপনি প্রতিটি অংশগ্রহণকারীর জন্য ডেটাফ্রেমের মতো প্রতিটি গ্রুপের সাথে কাজ করতে পারেন। এবং ডেটাফ্রেমগ্রুপবাই অবজেক্ট পদ্ধতি যেমন (প্রয়োগ, রূপান্তর, সমষ্টি, মাথা, প্রথম, শেষ) কোনও ডেটা ফ্রেম অবজেক্ট ফেরত দেয়।

অথবা আপনি তালিকা থেকে তালিকা তৈরি করতে groupedএবং সূচি অনুসারে সমস্ত ডেটা ফ্রেম পেতে পারেন :

l_grouped = list(grouped)

l_grouped[0][1] - প্রথম নাম সহ প্রথম গ্রুপের জন্য ডেটাফ্রেম।


7

গুসেভ স্লাভা জবাব ছাড়াও, আপনি গ্রুপবাইয়ের গ্রুপগুলি ব্যবহার করতে পারেন:

{key: df.loc[value] for key, value in df.groupby("name").groups.items()}

এটি আপনার দ্বারা বিভাজনযুক্ত কীগুলি সমেত পার্টিশনগুলিকে নির্দেশ করে একটি অভিধান উত্পন্ন করবে। সুবিধাটি হ'ল কীগুলি বজায় রাখা হয় এবং তালিকার সূচীতে নিখোঁজ হয় না।


3
In [28]: df = DataFrame(np.random.randn(1000000,10))

In [29]: df
Out[29]: 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 999999
Data columns (total 10 columns):
0    1000000  non-null values
1    1000000  non-null values
2    1000000  non-null values
3    1000000  non-null values
4    1000000  non-null values
5    1000000  non-null values
6    1000000  non-null values
7    1000000  non-null values
8    1000000  non-null values
9    1000000  non-null values
dtypes: float64(10)

In [30]: frames = [ df.iloc[i*60:min((i+1)*60,len(df))] for i in xrange(int(len(df)/60.) + 1) ]

In [31]: %timeit [ df.iloc[i*60:min((i+1)*60,len(df))] for i in xrange(int(len(df)/60.) + 1) ]
1 loops, best of 3: 849 ms per loop

In [32]: len(frames)
Out[32]: 16667

এখানে একটি গ্রুপবাই উপায় (এবং আপনি যোগফলের চেয়ে স্বেচ্ছাসেবক প্রয়োগ করতে পারেন)

In [9]: g = df.groupby(lambda x: x/60)

In [8]: g.sum()    

Out[8]: 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 16667 entries, 0 to 16666
Data columns (total 10 columns):
0    16667  non-null values
1    16667  non-null values
2    16667  non-null values
3    16667  non-null values
4    16667  non-null values
5    16667  non-null values
6    16667  non-null values
7    16667  non-null values
8    16667  non-null values
9    16667  non-null values
dtypes: float64(10)

সামিটটি সাইথোনাইজড তাই এটি এত দ্রুত

In [10]: %timeit g.sum()
10 loops, best of 3: 27.5 ms per loop

In [11]: %timeit df.groupby(lambda x: x/60)
1 loops, best of 3: 231 ms per loop

1

তালিকা বোঝার উপর ভিত্তি করে পদ্ধতি এবং groupby- যা তালিকার ভেরিয়েবলের মধ্যে সমস্ত বিভক্ত ডেটাফ্রেম সংরক্ষণ করে এবং সূচকটি ব্যবহার করে অ্যাক্সেস করা যায়।

উদাহরণ

ans = [pd.DataFrame(y) for x, y in DF.groupby('column_name', as_index=False)]

ans[0]
ans[0].column_name

1
  • প্রথমত, ওপিতে পদ্ধতিটি কার্যকর হয় তবে কার্যকর নয়। এটি চিরকালের জন্য চলতে পারে বলে মনে হচ্ছে, কারণ ডেটাসেটটি দীর্ঘ ছিল।
  • কলামটিতে ব্যবহার .groupbyকরুন 'method', এবং dictএর DataFramesসাথে 'method'কী হিসাবে অনন্য মানগুলির একটি তৈরি করুনdict-comprehension
    • .groupbyএকটি ফেরৎ groupbyবস্তু, যে গোষ্ঠী, যেখানে সম্পর্কে তথ্য রয়েছে gঅনন্য মান 'method'প্রতিটি দলের জন্য, এবং dহয় DataFrameযে দলের জন্য।
  • valueপ্রতিটি keyমধ্যে df_dict, একটি হতে হবে DataFrameযেটি মান ভাবে অ্যাক্সেস করা যেতে পারে,df_dict['key']
  • মূল প্রশ্ন চেয়েছিলেন একটি listএর DataFramesযা সঙ্গে সম্পন্ন করা যেতে পারে,list-comprehension
    • df_list = [d for _, d in df.groupby('method')]
import pandas as pd
import seaborn as sns  # for test dataset

# load data for example
df = sns.load_dataset('planets')

# display(df.head())
            method  number  orbital_period   mass  distance  year
0  Radial Velocity       1         269.300   7.10     77.40  2006
1  Radial Velocity       1         874.774   2.21     56.95  2008
2  Radial Velocity       1         763.000   2.60     19.84  2011
3  Radial Velocity       1         326.030  19.40    110.62  2007
4  Radial Velocity       1         516.220  10.50    119.47  2009


# Using a dict-comprehension, the unique 'method' value will be the key
df_dict = {g: d for g, d in df.groupby('method')}

print(df_dict.keys())
[out]:
dict_keys(['Astrometry', 'Eclipse Timing Variations', 'Imaging', 'Microlensing', 'Orbital Brightness Modulation', 'Pulsar Timing', 'Pulsation Timing Variations', 'Radial Velocity', 'Transit', 'Transit Timing Variations'])

# or a specific name for the key, using enumerate (e.g. df1, df2, etc.)
df_dict = {f'df{i}': d for i, (g, d) in enumerate(df.groupby('method'))}

print(df_dict.keys())
[out]:
dict_keys(['df0', 'df1', 'df2', 'df3', 'df4', 'df5', 'df6', 'df7', 'df8', 'df9'])
  • df_dict['df1].head(3) বা df_dict['Astrometry'].head(3)
  • এই গ্রুপে আছে মাত্র 2 জন
         method  number  orbital_period  mass  distance  year
113  Astrometry       1          246.36   NaN     20.77  2013
537  Astrometry       1         1016.00   NaN     14.98  2010
  • df_dict['df2].head(3) বা df_dict['Eclipse Timing Variations'].head(3)
                       method  number  orbital_period  mass  distance  year
32  Eclipse Timing Variations       1         10220.0  6.05       NaN  2009
37  Eclipse Timing Variations       2          5767.0   NaN    130.72  2008
38  Eclipse Timing Variations       2          3321.0   NaN    130.72  2008
  • df_dict['df3].head(3) বা df_dict['Imaging'].head(3)
     method  number  orbital_period  mass  distance  year
29  Imaging       1             NaN   NaN     45.52  2005
30  Imaging       1             NaN   NaN    165.00  2007
31  Imaging       1             NaN   NaN    140.00  2004

বিকল্পভাবে

  • পৃথক DataFramesব্যবহার করে তৈরি করার জন্য এটি একটি ম্যানুয়াল পদ্ধতিপান্ডাস : বুলিয়ান সূচক
  • এটি গৃহীত উত্তরের মতো , তবে.loc প্রয়োজন নেই।
  • এটি একটি দম্পতি অতিরিক্ত তৈরি করার জন্য একটি গ্রহণযোগ্য পদ্ধতি DataFrames
  • Pythonic উপায় একাধিক বস্তু তৈরি করতে (যেমন একটি কন্টেইনারে তাদের স্থাপন করে dict, list, generatorউপরে দেখানো, ইত্যাদি)।
df1 = df[df.method == 'Astrometry']
df2 = df[df.method == 'Eclipse Timing Variations']

0

আপনার কাছে ইতিমধ্যে আপনার ডেটার জন্য কিছু লেবেল থাকলে আপনি গ্রুপবাই কমান্ডটি ব্যবহার করতে পারেন।

 out_list = [group[1] for group in in_series.groupby(label_series.values)]

এখানে একটি বিস্তারিত উদাহরণ:

ধরা যাক আমরা কিছু লেবেল ব্যবহার করে খণ্ডের তালিকায় একটি পিডি সিরিজ ভাগ করতে চাই উদাহরণস্বরূপ in_series:

2019-07-01 08:00:00   -0.10
2019-07-01 08:02:00    1.16
2019-07-01 08:04:00    0.69
2019-07-01 08:06:00   -0.81
2019-07-01 08:08:00   -0.64
Length: 5, dtype: float64

এবং এটি সম্পর্কিত label_series:

2019-07-01 08:00:00   1
2019-07-01 08:02:00   1
2019-07-01 08:04:00   2
2019-07-01 08:06:00   2
2019-07-01 08:08:00   2
Length: 5, dtype: float64

চালান

out_list = [group[1] for group in in_series.groupby(label_series.values)]

যা দুটির out_listএকটি listপ্রদান করে pd.Series:

[2019-07-01 08:00:00   -0.10
2019-07-01 08:02:00   1.16
Length: 2, dtype: float64,
2019-07-01 08:04:00    0.69
2019-07-01 08:06:00   -0.81
2019-07-01 08:08:00   -0.64
Length: 3, dtype: float64]

মনে রাখবেন যে আপনি in_seriesনিজের থেকে সিরিজটি গোছাতে কিছু প্যারামিটার ব্যবহার করতে পারেন , যেমন,in_series.index.day


-1

আমারও একই সমস্যা ছিল আমার 10 টি বিভিন্ন স্টোর এবং 50 টি বিভিন্ন আইটেমের জন্য দৈনিক বিক্রয়ের একটি সময় সিরিজ ছিল। তাদের প্রত্যেকটিতে মেশিন লার্নিং মডেল প্রয়োগ করার জন্য আমার মূল ডেটাফ্রেমটি 500 ডেটাফ্রেমে (10 স্টোর * 50 স্টোর) বিভক্ত করার প্রয়োজন ছিল এবং আমি নিজে এটি করতে পারিনি।

এটি ডেটাফ্রেমের প্রধান:

ডেটাফ্রেমের প্রধান: ডিএফ

আমি দুটি তালিকা তৈরি করেছি; ডেটাফ্রেমগুলির নামের জন্য একটি এবং অ্যারে [আইটেম_ নাম্বার, স্টোর_নম্বার] এর জন্য একটি

    list=[]
    for i in range(1,len(items)*len(stores)+1):
    global list
    list.append('df'+str(i))

    list_couple_s_i =[]
    for item in items:
          for store in stores:
                  global list_couple_s_i
                  list_couple_s_i.append([item,store])

এবং একবার দুটি তালিকা প্রস্তুত হয়ে গেলে আপনি যে ডেটাফ্রেমগুলি চান তা তৈরি করতে তাদের লুপ করতে পারেন:

         for name, it_st in zip(list,list_couple_s_i):
                   globals()[name] = df.where((df['item']==it_st[0]) & 
                                                (df['store']==(it_st[1])))
                   globals()[name].dropna(inplace=True)

এইভাবে আমি 500 ডেটা ফ্রেম তৈরি করেছি।

আশা করি এটি সহায়ক হবে!

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