পান্ডারা ডেটাফ্রেমকে টিপলসের অ্যারে রূপান্তর করে


131

আমি পান্ডা ব্যবহার করে কিছু ডেটা ম্যানিপুলেটেড করেছি এবং এখন আমি একটি ব্যাচ সংরক্ষণ করে ডেটাবেসে ফিরে যেতে চাই। এটির জন্য আমাকে ডাটাফ্রেমের ডেটাফ্রেমের একটি "সারি" অনুসারে প্রতিটি টিপলকে টিপলসের একটি অ্যারে রূপান্তর করতে হবে।

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

In [182]: data_set
Out[182]: 
  index data_date   data_1  data_2
0  14303 2012-02-17  24.75   25.03 
1  12009 2012-02-16  25.00   25.07 
2  11830 2012-02-15  24.99   25.15 
3  6274  2012-02-14  24.68   25.05 
4  2302  2012-02-13  24.62   24.77 
5  14085 2012-02-10  24.38   24.61 

আমি এটিকে টিপলগুলির একটি অ্যারেতে রূপান্তর করতে চাই:

[(datetime.date(2012,2,17),24.75,25.03),
(datetime.date(2012,2,16),25.00,25.07),
...etc. ]

আমি কীভাবে দক্ষতার সাথে এটি করতে পারি তার কোনও পরামর্শ?


21
2017+ এ এই উত্তরটিতে যারা আসছেন তাদের জন্য নীচে একটি নতুন প্রতিমা সমাধান রয়েছে । আপনি কেবল ব্যবহার করতে পারেনlist(df.itertuples(index=False, name=None))
টেড পেট্রো

3
আমি যখন এই প্রশ্নটিতে আসি তখন দুটি জিনিস আমি খুঁজতে চাইছি: টিপলগুলির df.to_records(index=False)একটি তালিকা - এবং ডিক্টের একটি তালিকা:df.to_dict('records')
মার্টিন থোমা

@ মার্টিনথোমা টু_রেকার্ড এবং টু ডিক্ট ('রেকর্ডস') উভয়ই আমার ডেটা-টাইপ স্ক্রু করে। জানা বাগ কিন্তু এই সমাধানগুলি অকেজো করে তোলে ...
জোচেন

উত্তর:


206

কেমন:

subset = data_set[['data_date', 'data_1', 'data_2']]
tuples = [tuple(x) for x in subset.to_numpy()]

পান্ডাস <0.24 ব্যবহারের জন্য

tuples = [tuple(x) for x in subset.values]

2
দয়া করে নীচের @ কিসিন্ডির উত্তরটি ব্যবহারের জন্য দেখুন .itertuples, যা অ্যারে হিসাবে মানগুলি পেতে এবং এগুলিকে একটি টিউপলে জ্বালিয়ে দেওয়ার চেয়ে আরও কার্যকর।
vy32

1
সামান্য ক্লিনারটি হ'ল: টিউপলস = ম্যাপ (টিপল, সাবসেট.ভেলিউস)
রুফাসভিএস

এটি মানকে ভিন্ন ধরণের দিতে পারে, তাই না?
এএমসি

160
list(data_set.itertuples(index=False))

১.1.১-এর হিসাবে উপরেরগুলি নেমটুপলগুলির একটি তালিকা ফিরিয়ে দেবে

আপনি যদি সাধারণ টিপলগুলির একটি তালিকা চান তবে একটি name=Noneআর্গুমেন্ট হিসাবে পাস করুন :

list(data_set.itertuples(index=False, name=None))

39
এটি গ্রহণযোগ্য উত্তর আইএমএইচও হওয়া উচিত (এখন যে কোনও উত্সর্গীকৃত বৈশিষ্ট্য বিদ্যমান)। বিটিডাব্লু, আপনি যদি tupleনিজের zipপুনরুক্তিতে ( namedtupleগুলি পরিবর্তে ) সাধারণ ব্যবহার করতে চান তবে ফোন করুন:data_set.itertuples(index=False, name=None)
এক্সেল


3
@ কোল্ডস্পিডে লিঙ্কিত প্রশ্ন থেকে আমি যে পাঠটি পেয়েছি তা হ'ল ইটার্টুপলস ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে পরিবর্তিত হওয়া / ভেক্টরাইজড / সাইথন অপারেশনগুলির চেয়ে ধীর হয় is এই প্রশ্নটি টিপলসে রূপান্তর করতে বলছে, এমন কোনও কারণ আছে যা আমরা মনে করি যে গৃহীত উত্তরটি দ্রুত? আমি যে দ্রুত পরীক্ষাটি করেছি তা ইঙ্গিত দেয় যে এরটুপলস সংস্করণটি দ্রুত is
টিসি প্রক্টর 19


1
@ জোহানডাঙ্গার এটি পাইথনে ইওল () এবং গ্লোবাল () এর ধারণার অনুরূপ। প্রত্যেকেই জানেন যে তাদের অস্তিত্ব রয়েছে। প্রত্যেকে আরও জানে যে আপনার সাধারণত এই ফাংশনগুলি ব্যবহার করা উচিত নয় কারণ এটি খারাপ ফর্ম হিসাবে বিবেচিত। এখানে মূলনীতিটি একই রকম, পান্ডসে ইটার * পরিবারকে ব্যবহার করার জন্য খুব কম কেস রয়েছে, এটি তর্কাতীতভাবে একটি one আমি তখনও একটি আলাদা পদ্ধতি ব্যবহার করব (যেমন একটি লিখিত কমপ বা মানচিত্র) তবে এটি আমি।
cs95


30

অনুপ্রেরণা
অনেক ডেটা সেট যথেষ্ট বড় যে আমাদের গতি / দক্ষতার সাথে আমাদের উদ্বেগ করা উচিত। তাই আমি এই আত্মার মধ্যে এই সমাধান অফার। এটি সংহত হওয়াও ঘটে।

তুলনার খাতিরে, আসুন indexকলামটি বাদ দিন

df = data_set.drop('index', 1)

সমাধান
আমি ব্যবহার উত্থাপন করা হবে zipএবংmap

list(zip(*map(df.get, df)))

[('2012-02-17', 24.75, 25.03),
 ('2012-02-16', 25.0, 25.07),
 ('2012-02-15', 24.99, 25.15),
 ('2012-02-14', 24.68, 25.05),
 ('2012-02-13', 24.62, 24.77),
 ('2012-02-10', 24.38, 24.61)]

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

list(zip(*map(df.get, ['data_date', 'data_1', 'data_2'])))

[('2012-02-17', 24.75, 25.03),
 ('2012-02-16', 25.0, 25.07),
 ('2012-02-15', 24.99, 25.15),
 ('2012-02-14', 24.68, 25.05),
 ('2012-02-13', 24.62, 24.77),
 ('2012-02-10', 24.38, 24.61)]

দ্রুত কি?

টার্ন recordsআউটটি অ্যাসিম্পটোটিক্যালি রূপান্তরিত zipmapএবং এরপরে দ্রুতiter_tuples

আমি এই পোস্টটিsimple_benchmarks থেকে পেয়েছি এমন একটি লাইব্রেরি ব্যবহার করব

from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()

import pandas as pd
import numpy as np

def tuple_comp(df): return [tuple(x) for x in df.to_numpy()]
def iter_namedtuples(df): return list(df.itertuples(index=False))
def iter_tuples(df): return list(df.itertuples(index=False, name=None))
def records(df): return df.to_records(index=False).tolist()
def zipmap(df): return list(zip(*map(df.get, df)))

funcs = [tuple_comp, iter_namedtuples, iter_tuples, records, zipmap]
for func in funcs:
    b.add_function()(func)

def creator(n):
    return pd.DataFrame({"A": random.randint(n, size=n), "B": random.randint(n, size=n)})

@b.add_arguments('Rows in DataFrame')
def argument_provider():
    for n in (10 ** (np.arange(4, 11) / 2)).astype(int):
        yield n, creator(n)

r = b.run()

ফলাফলগুলি পরীক্ষা করুন

r.to_pandas_dataframe().pipe(lambda d: d.div(d.min(1), 0))

        tuple_comp  iter_namedtuples  iter_tuples   records    zipmap
100       2.905662          6.626308     3.450741  1.469471  1.000000
316       4.612692          4.814433     2.375874  1.096352  1.000000
1000      6.513121          4.106426     1.958293  1.000000  1.316303
3162      8.446138          4.082161     1.808339  1.000000  1.533605
10000     8.424483          3.621461     1.651831  1.000000  1.558592
31622     7.813803          3.386592     1.586483  1.000000  1.515478
100000    7.050572          3.162426     1.499977  1.000000  1.480131

r.plot()

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


12

এখানে একটি ভেক্টরাইজড অ্যাপ্রোচ (ডেটাফ্রেম ধরে ধরে, পরিবর্তে data_setসংজ্ঞায়িত করা df) যা দেখানো হয়েছে তার একটি listপ্রদান করে tuples:

>>> df.set_index(['data_date'])[['data_1', 'data_2']].to_records().tolist()

সৃষ্টি করে:

[(datetime.datetime(2012, 2, 17, 0, 0), 24.75, 25.03),
 (datetime.datetime(2012, 2, 16, 0, 0), 25.0, 25.07),
 (datetime.datetime(2012, 2, 15, 0, 0), 24.99, 25.15),
 (datetime.datetime(2012, 2, 14, 0, 0), 24.68, 25.05),
 (datetime.datetime(2012, 2, 13, 0, 0), 24.62, 24.77),
 (datetime.datetime(2012, 2, 10, 0, 0), 24.38, 24.61)]

সূচক অক্ষ হিসাবে ডেটটাইম কলাম সেট করার ধারণাটি হ'ল ডেটাফ্রেমের জন্য যুক্তিযুক্ত যুক্তিটি ব্যবহার করে Timestampএটির সাথে সংশ্লিষ্ট রূপের datetime.datetimeসমতুল্য রূপান্তর করতে সহায়তা করে ।convert_datetime64DF.to_recordsDateTimeIndex

এটি এমন একটি প্রত্যাবর্তন করে recarrayযা এর পরে listব্যবহার করে ফেরত দেওয়া যেতে পারে.tolist


ব্যবহারের ক্ষেত্রে নির্ভর করে আরও সাধারণ সমাধান হবে:

df.to_records().tolist()                              # Supply index=False to exclude index

10

সবচেয়ে কার্যকর এবং সহজ উপায়:

list(data_set.to_records())

আপনি এই কল করার আগে আপনার প্রয়োজনীয় কলামগুলি ফিল্টার করতে পারবেন।


1
আমি মনে করি 'সূচি = মিথ্যা' to_record () এর আর্গুমেন্ট হিসাবে দেওয়া উচিত। সুতরাং, তালিকা (ডেটা_সেট.টো_েরেকর্ডস (সূচক = মিথ্যা))
ব্যবহারকারী 34151567

8

এই উত্তরটি এমন কোনও উত্তর যুক্ত করে না যা ইতিমধ্যে আলোচনা করা হয়নি, তবে এখানে কিছু গতির ফলাফল রয়েছে। আমি মনে করি এটি মন্তব্যে উঠে আসা প্রশ্নগুলির সমাধান করা উচিত। এই তিনটি মানের উপর ভিত্তি করে এগুলির সমস্ত দেখতে ও (এন) এর মতো দেখাচ্ছে ।

টিএল; ডিআর : tuples = list(df.itertuples(index=False, name=None))এবং tuples = list(zip(*[df[c].values.tolist() for c in df]))দ্রুততম জন্য বাঁধা হয়।

আমি এখানে তিনটি পরামর্শের জন্য ফলাফলগুলির দ্রুত গতি পরীক্ষা করেছি:

  1. @ পারস্পরিকের থেকে জিপ উত্তর: tuples = list(zip(*[df[c].values.tolist() for c in df]))
  2. @ ওয়েজ-ম্যাকিনে থেকে গৃহীত উত্তর: tuples = [tuple(x) for x in df.values]
  3. @ আকসিলের name=Noneপরামর্শ অনুসারে ইটারটুপলস উত্তর @ অ্যাকসিন্ডি থেকে:tuples = list(df.itertuples(index=False, name=None))
from numpy import random
import pandas as pd


def create_random_df(n):
    return pd.DataFrame({"A": random.randint(n, size=n), "B": random.randint(n, size=n)})

ছোট আকার:

df = create_random_df(10000)
%timeit tuples = list(zip(*[df[c].values.tolist() for c in df]))
%timeit tuples = [tuple(x) for x in df.values]
%timeit tuples = list(df.itertuples(index=False, name=None))

দেয়:

1.66 ms ± 200 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
15.5 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
1.74 ms ± 75.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

বড় আকারের:

df = create_random_df(1000000)
%timeit tuples = list(zip(*[df[c].values.tolist() for c in df]))
%timeit tuples = [tuple(x) for x in df.values]
%timeit tuples = list(df.itertuples(index=False, name=None))

দেয়:

202 ms ± 5.91 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
1.52 s ± 98.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
209 ms ± 11.8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

আমার যতটা ধৈর্য রয়েছে:

df = create_random_df(10000000)
%timeit tuples = list(zip(*[df[c].values.tolist() for c in df]))
%timeit tuples = [tuple(x) for x in df.values]
%timeit tuples = list(df.itertuples(index=False, name=None))

দেয়:

1.78 s ± 118 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
15.4 s ± 222 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1.68 s ± 96.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

জিপ সংস্করণ এবং ইটারটুপলস সংস্করণ একে অপরের আত্মবিশ্বাসের ব্যবধানের মধ্যে থাকে। আমি সন্দেহ করি যে তারা হুডের নীচে একই কাজ করছে।

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


আমি আমার বাসি পোস্ট আপডেট করেছি। আমি কিছু সময়ের [*zip(*map(df.get, df))]জন্য ব্যবহার করা হয়েছে । যাইহোক, ভেবেছি আপনি এটি আকর্ষণীয় মনে হবে।
পাইরেসওয়ার্ড

পছন্দ করুন আমি সুন্দর প্লট পছন্দ। আমি এটি সম্পর্কে মত যে কেমন লাগে হে (ঢ)
টিসি প্রক্টর

2
#try this one:

tuples = list(zip(data_set["data_date"], data_set["data_1"],data_set["data_2"]))
print (tuples)

2

টিউপসগুলির তালিকায় ডেটা ফ্রেমের তালিকা পরিবর্তন করা।

df = pd.DataFrame({'col1': [1, 2, 3], 'col2': [4, 5, 6]})
print(df)
OUTPUT
   col1  col2
0     1     4
1     2     5
2     3     6

records = df.to_records(index=False)
result = list(records)
print(result)
OUTPUT
[(1, 4), (2, 5), (3, 6)]

1
দয়া করে একটি উত্তর হিসাবে কেবল কোড পোস্ট করবেন না, তবে আপনার কোডটি কী করে এবং কীভাবে এটি সমস্যার সমস্যার সমাধান করে তা একটি ব্যাখ্যা সরবরাহ করুন। একটি ব্যাখ্যা সহ উত্তরগুলি সাধারণত উচ্চমানের হয়, এবং উন্নতদের আকর্ষণ করার সম্ভাবনা বেশি থাকে।
মার্ক রোটভিল

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