ডেটাফ্রেমে পুনরাবৃত্ত "কী = মান" জোড়ার ফাইলটি পড়ুন


11

আমার এই ফর্ম্যাটটিতে ডেটা সহ একটি টেক্সট ফাইল রয়েছে। প্রথম 3 লাইন বার বার পুনরাবৃত্তি করে।

name=1
grade=A
class=B
name=2
grade=D
class=A

আমি একটি টেবিল বিন্যাসে ডেটা আউটপুট করতে চাই, উদাহরণস্বরূপ:

name | grade | class
1    | A     | B
2    | D     | A

আমি শিরোনামগুলি সেট করতে সংগ্রাম করছি এবং কেবলমাত্র ডেটা লুপ করছি। আমি এখন পর্যন্ত যা চেষ্টা করেছি তা হ'ল:

def myfile(filename):
    with open(file1) as f:
        for line in f:
            yield line.strip().split('=',1)

def pprint_df(dframe):
    print(tabulate(dframe, headers="keys", tablefmt="psql", showindex=False,))

#f = pd.DataFrame(myfile('file1')
df = pd.DataFrame(myfile('file1'))
pprint_df(df)

যে আউটপুট হয়

+-------+-----+
| 0     | 1   |
|-------+-----|
| name  | 1   |
| grade | A   |
| class | B   |
| name  | 2   |
| grade | D   |
| class | A   |
+-------+-----+

আমি যা খুঁজছি তা আসলে নয়।

উত্তর:


2

এই সমাধানটি আপনার বর্ণনার মতো পাঠ্য বিন্যাসটি ধরে নিয়েছে তবে নতুন লাইনের সূচনা বোঝাতে আপনি আলাদা শব্দ ব্যবহার করতে এটি পরিবর্তন করতে পারেন। এখানে, আমরা ধরে নিই যে nameক্ষেত্রটি দিয়ে একটি নতুন লাইন শুরু হয় । আমি myfile()নীচে আপনার ফাংশনটি পরিবর্তন করেছি , আশা করি এটি আপনাকে কিছু ধারণা দেয় :)

def myfile(filename):
    d_list = []
    with open(filename) as f:
        d_line = {}
        for line in f:
            split_line = line.rstrip("\n").split('=')  # Strip \n characters and split field and value.
            if (split_line[0] == 'name'):
                if d_line:
                    d_list.append(d_line)  # Append if there is previous line in d_line.
                d_line = {split_line[0]: split_line[1]}  # Start a new dictionary to collect the next lines.
            else:
                d_line[split_line[0]] = split_line[1]  # Add the other 2 fields to the dictionary.
        d_list.append(d_line) # Append the last line.
    return pd.DataFrame(d_list)  # Turn the list of dictionaries into a DataFrame.

10

আপনি ফাইলটি পড়তে এবং ডেটা প্রক্রিয়া করতে পান্ডাস ব্যবহার করতে পারেন। আপনি এটি ব্যবহার করতে পারেন:

import pandas as pd
df = pd.read_table(r'file.txt', header=None)
new = df[0].str.split("=", n=1, expand=True)
new['index'] = new.groupby(new[0])[0].cumcount()
new = new.pivot(index='index', columns=0, values=1)

new আউটপুট:

0     class grade name
index                 
0         B     A    1
1         A     D    2

যোগ করুন df = pd.read_table(file, header=None), নিম্নলিখিত লাইনটি তৈরি করুন new = df[0].str.split("=", n=1, expand=True)এবং এটি "চমৎকার কোড" এর ক্ষেত্রে আমার প্রিয় উত্তর হবে।
মিঃফুপ্পেস

@ এমআরফুপেস আমি আমার উত্তর সম্পাদনা করেছি। ইঙ্গিতটির জন্য ধন্যবাদ।
luigigi

1
+1 ;-) তবে, আমি %timeitআমার উত্তরের বিরুদ্ধে কেবল দৌড়ে এসেছি এবং খাঁটি-পান্ডাস দ্রবণটি কত ধীর গতিতে পেরেছি। এটি আমার মেশিনে প্রায় x7 ধীর ছিল (খুব ছোট ইনপুট txt ফাইলের জন্য)! সুবিধার সাথে ওভারহেড আসে, ওভারহেড (বেশিরভাগ সময়) আসে পারফরম্যান্সে লোকসান ...
মিঃফুপ্পেস

7

আমি জানি আপনার যথেষ্ট উত্তর আছে তবে অভিধান ব্যবহার করে এটি করার আরও একটি উপায় এখানে রয়েছে:

import pandas as pd
from collections import defaultdict
d = defaultdict(list)

with open("text_file.txt") as f:
    for line in f:
        (key, val) = line.split('=')
        d[key].append(val.replace('\n', ''))

df = pd.DataFrame(d)
print(df)

এটি আপনাকে ফলাফল হিসাবে দেয়:

name grade class
0    1     A     B
1    2     D     A

শুধু অন্য দৃষ্টিকোণ পেতে।


3

যেহেতু আপনি একটি আউটপুট পেয়েছেন আমি কীভাবে সমস্যার মোকাবেলা করব:

প্রথমে কলামগুলির পুনরাবৃত্তির ভিত্তিতে একটি অনন্য সূচক তৈরি করুন,

df['idx'] = df.groupby(df['0'])['0'].cumcount() + 1
print(df)
        0  1  idx
0   name  1      1
1  grade  A      1
2  class  B      1
3   name  2      2
4  grade  D      2
5  class  A      2

আমরা কি তবে এটি ব্যবহার ব্যবহার করে আপনার dataframe পিভট crosstabফাংশন

df1 = pd.crosstab(df['idx'],df['0'],values=df['1'],aggfunc='first').reset_index(drop=True)
print(df1[['name','grade','class']])
0 name grade class
0    1     A     B
1    2     D     A

3

আপনি যা করতে পারেন তা হ'ল file3 এর ব্লকে আপনার পাঠ্য ফাইলটি পড়া , নেস্টেড তালিকা তৈরি করা এবং এটি একটি ডেটাফ্রেমে রাখা:

from itertools import zip_longest
import pandas as pd

# taken from https://docs.python.org/3.7/library/itertools.html:
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

data = [['name', 'grade', 'class']]
with open(file, 'r') as fobj:
    blocks = grouper(fobj, 3)
    for b in blocks:
        data.append([i.split('=')[-1].strip() for i in b])

df = pd.DataFrame(data[1:], columns=data[0])  

df সরাসরি হবে

  name grade class
0    1     A     B
1    2     D     A

নোট # 1: যদিও এটি খাঁটি pandasসমাধানের চেয়ে কোডের আরও লাইন তৈরি করে , আমার অভিজ্ঞতাতে এটি সম্ভবত আরও কার্যকর হতে পারে কারণ এটি কম pandasকার্যকারিতা যেমন কম ওভারহেড ব্যবহার করে।

নোট # 2: সাধারণভাবে আমি যুক্তি দিয়ে বলতে পারি যে আপনার ইনপুট ডেটা অন্য ফর্ম্যাটে সংরক্ষণ করা ভাল, যেমন jsonবা csv। এটি পড়তে আরও সহজ pandasকরে তুলবে , উদাহরণস্বরূপ, সিএসভি ফাইলের ক্ষেত্রে রিড_সিএসভি ফাংশন সহ


0

পাইথনের অভিধান মডিউল এবং পান্ডাস ব্যবহার করে আপনি সেই আউটপুট তৈরি করতে পারেন ।

import pandas as pd
from collections import defaultdict

text = '''name=1
          grade=A
          class=B
          name=2
          grade=D
          class=A'''
text = text.split()

new_dict = defaultdict(list) 
for i in text:
    temp = i.split('=')
    new_dict[temp[0]].append(temp[1])

df = pd.DataFrame(new_dict)

এই পদ্ধতির সবচেয়ে দক্ষ এক নাও হতে পারে তবে এটি পান্ডসের উন্নত ফাংশনগুলির কোনও ব্যবহার করে না। আশা করি এটা সাহায্য করবে.

আউটপুট:

    name    grade   class
0      1        A       B
1      2        D       A

0

আইএমএইচও, সমস্ত বর্তমান উত্তর খুব জটিল দেখাচ্ছে। আমি যা করব তা হ'ল 2 টি কলাম পড়ার প্যারামিটার '='হিসাবে ব্যবহার করা এবং তারপরে প্রাপ্ত ডেটাফ্রেম:seppd.read_csvpivot

import pandas as pd

df = pd.read_csv('myfile', sep='=', header=None)
#        0  1
# 0   name  1
# 1  grade  A
# 2  class  B
# 3   name  2
# 4  grade  D
# 5  class  A

df = df.pivot(index=df.index // len(df[0].unique()), columns=0)
#       1           
# 0 class grade name
# 0     B     A    1
# 1     A     D    2

আপনি যদি ফলাফলটিতে সেই বহু-স্তরের কলাম সূচকটি না চান তবে আপনি এটি দ্বারা মুছে ফেলতে পারেন:

df.columns = df.columns.get_level_values(1)
# 0 class grade name
# 0     B     A    1
# 1     A     D    2
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.