पंडों ने डेटाफ्रेम को ट्यूपल्स के सरणी में बदल दिया


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')
मार्टिन थोमा

@MartinThoma दोनों to_records और to_dict ('रिकॉर्ड्स') मेरे डेटा-प्रकार को स्क्रू करते हैं। ज्ञात बग लेकिन इस समाधान को बेकार बनाता है ...
जोचेन

जवाबों:


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
कृपया उपयोग करने के लिए नीचे दिए गए @ ksindi के उत्तर को देखें .itertuples, जो एक सरणी के रूप में मान प्राप्त करने और उन्हें टुप में रखने से अधिक कुशल होगा।
22:32

1
थोड़ा साफ है: tuples = map (tuple, subset.values)
RufusVS

यह मानों को एक अलग प्रकार में डाल सकता है, हालांकि, सही?
एएमसी

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

17.1 के अनुसार, ऊपर उल्लिखित नेमप्लस की एक सूची होगी ।

यदि आप सामान्य टुपल्स की सूची चाहते हैं, तो name=Noneएक तर्क के रूप में पास करें :

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

39
यह स्वीकृत उत्तर IMHO होना चाहिए (अब है कि एक समर्पित सुविधा मौजूद है)। BTW, यदि आप tupleअपने zipitter ( namedtuples के बजाय ) में सामान्य s चाहते हैं , तो कॉल करें:data_set.itertuples(index=False, name=None)
Axel


3
@coldspeed लिंक किए गए प्रश्न से मुझे जो सबक मिला है वह यह है कि इटर्अपल्स धीमा है क्योंकि ट्यूपल्स में परिवर्तित करना आमतौर पर वेक्टराइज्ड / साइथॉन ऑपरेशंस की तुलना में धीमा होता है। यह देखते हुए कि सवाल ट्यूपल्स में बदलने के लिए कह रहा है, क्या कोई कारण है कि हम सोचेंगे कि स्वीकृत उत्तर तेज है? मैंने जो त्वरित परीक्षण किया, वह बताता है कि इटर्अपल्स संस्करण तेज़ है।
टीसी प्रॉक्टर


1
@ जॉनडैंगर यह अजगर में eval () और ग्लोबल्स () की अवधारणा के समान है। हर कोई जानता है कि वे मौजूद हैं। हर कोई यह भी जानता है कि आपको आमतौर पर इन कार्यों का उपयोग नहीं करना चाहिए क्योंकि यह खराब रूप माना जाता है। यहां सिद्धांत समान है, पांडा में परिवार * का उपयोग करने के लिए बहुत कम मामले हैं, यह यकीनन उनमें से एक है। मैं अब भी एक अलग विधि (जैसे एक सूची COMP या मानचित्र) का उपयोग करूँगा, लेकिन यह मैं हूँ।
सीएस 95


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

यहाँ एक vectorized दृष्टिकोण (dataframe, यह मानते हुए है 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.datetimeconvert_datetime64DF.to_recordsDateTimeIndex

यह एक रिटर्न recarrayजो एक listका उपयोग कर वापस करने के लिए बनाया जा सकता है.tolist


उपयोग के मामले के आधार पर अधिक सामान्यीकृत समाधान होगा:

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

10

सबसे कुशल और आसान तरीका:

list(data_set.to_records())

आप इस कॉल से पहले आवश्यक कॉलम फ़िल्टर कर सकते हैं।


1
मुझे लगता है कि 'इंडेक्स = गलत' को to_records () के तर्क के रूप में दिया जाना चाहिए। इस प्रकार, सूची (data_set.to_records (index = False))
user3415167

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. @ Wes-mckinney से स्वीकृत उत्तर: tuples = [tuple(x) for x in df.values]
  3. @ ऑक्सेल के name=Noneसुझाव के साथ @ksindi से itertuples उत्तर :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)

ज़िप संस्करण और इटर्टुपल्स संस्करण एक दूसरे के विश्वास अंतराल के भीतर हैं। मुझे संदेह है कि वे हुड के नीचे एक ही काम कर रहे हैं।

ये गति परीक्षण शायद अप्रासंगिक हैं। मेरे कंप्यूटर की मेमोरी की सीमा को बढ़ाने में बहुत अधिक समय नहीं लगता है, और आपको वास्तव में एक बड़े डेटा सेट पर ऐसा नहीं करना चाहिए। ऐसा करने के बाद उन tuples के साथ काम करना वास्तव में अक्षम हो जाएगा। यह आपके कोड में एक बड़ी अड़चन होने की संभावना नहीं है, इसलिए केवल उस संस्करण के साथ रहें जो आपको लगता है कि सबसे अधिक पठनीय है।


मैंने अपनी बासी पोस्ट को अपडेट किया। मैं [*zip(*map(df.get, df))]अब कुछ समय के लिए उपयोग कर रहा हूँ । वैसे भी, आपको यह दिलचस्प लगा।
piRSquared

@piRSquared ऊह। मुझे सुंदर प्लॉट पसंद है। मुझे लगता है कि ऐसा लगता है कि यह O (n) है
टीसी प्रॉक्टर

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
कृपया केवल कोड को एक उत्तर के रूप में पोस्ट न करें, बल्कि यह भी बताएं कि आपका कोड क्या करता है और यह कैसे प्रश्न की समस्या को हल करता है। स्पष्टीकरण के साथ उत्तर आमतौर पर उच्च गुणवत्ता वाले होते हैं, और अपवोट को आकर्षित करने की अधिक संभावना होती है।
मार्क रोटेटेवेल

1

अधिक पायथोनिक तरीका:

df = data_set[['data_date', 'data_1', 'data_2']]
map(tuple,df.values)

अधिक पायथोनिक तरीका: वास्तव में बिल्कुल विपरीत। map()कुख्यात है।
एएमसी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.