Pandas는 데이터 프레임을 튜플 배열로 변환합니다.
pandas를 사용하여 일부 데이터를 조작했으며 이제 데이터베이스에 일괄 저장을 수행하고 싶습니다. 이를 위해서는 데이터 프레임을 튜플 배열로 변환해야합니다. 각 튜플은 데이터 프레임의 "행"에 해당합니다.
내 DataFrame은 다음과 같습니다.
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. ]
이를 효율적으로 수행 할 수있는 방법에 대한 제안이 있습니까?
어때 :
subset = data_set[['data_date', 'data_1', 'data_2']]
tuples = [tuple(x) for x in subset.values]
list(data_set.itertuples(index=False))
17.1부터 위는 namedtuples 목록을 반환합니다 .
일반 튜플 목록을 원하면 name=None
인수로 전달하십시오.
list(data_set.itertuples(index=False, name=None))
일반적인 방법 :
[tuple(x) for x in data_set.to_records(index=False)]
동기 부여
많은 데이터 세트는 속도 / 효율성에 관심을 가질만큼 충분히 큽니다. 그래서 저는 그 정신으로이 솔루션을 제공합니다. 그것은 또한 간결합니다.
비교를 위해 index
열을 삭제하겠습니다.
df = data_set.drop('index', 1)
솔루션
사용 zip
및 이해를 제안합니다
list(zip(*[df[c].values.tolist() for c in 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(*[df[c].values.tolist() for c in ['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)]
다음은 모두 동일한 결과를 생성합니다.
[tuple(x) for x in df.values]
df.to_records(index=False).tolist()
list(map(tuple,df.values))
list(map(tuple, df.itertuples(index=False)))
더 빠른 것은 무엇입니까?
zip
이해력이 훨씬 빠릅니다.
%timeit [tuple(x) for x in df.values]
%timeit list(map(tuple, df.itertuples(index=False)))
%timeit df.to_records(index=False).tolist()
%timeit list(map(tuple,df.values))
%timeit list(zip(*[df[c].values.tolist() for c in df]))
작은 데이터
10000 loops, best of 3: 55.7 µs per loop
1000 loops, best of 3: 596 µs per loop
10000 loops, best of 3: 38.2 µs per loop
10000 loops, best of 3: 54.3 µs per loop
100000 loops, best of 3: 12.9 µs per loop
대용량 데이터
10 loops, best of 3: 58.8 ms per loop
10 loops, best of 3: 43.9 ms per loop
10 loops, best of 3: 29.3 ms per loop
10 loops, best of 3: 53.7 ms per loop
100 loops, best of 3: 6.09 ms per loop
다음 은 그림과 같이 of 를 반환 하는 벡터화 된 접근 방식 (데이터 프레임 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)]
The idea of setting datetime column as the index axis is to aid in the conversion of the Timestamp
value to it's corresponding datetime.datetime
format equivalent by making use of the convert_datetime64
argument in DF.to_records
which does so for a DateTimeIndex
dataframe.
This returns a recarray
which could be then made to return a list
using .tolist
More generalized solution depending on the use case would be:
df.to_records().tolist() # Supply index=False to exclude index
This answer doesn't add any answers that aren't already discussed, but here are some speed results. I think this should resolve questions that came up in the comments. All of these look like they are O(n), based on these three values.
TL;DR: tuples = list(df.itertuples(index=False, name=None))
and tuples = list(zip(*[df[c].values.tolist() for c in df]))
are tied for the fastest.
I did a quick speed test on results for three suggestions here:
- The zip answer from @pirsquared:
tuples = list(zip(*[df[c].values.tolist() for c in df]))
- The accepted answer from @wes-mckinney:
tuples = [tuple(x) for x in df.values]
- The itertuples answer from @ksindi with the
name=None
suggestion from @Axel: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)})
Small size:
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))
Gives:
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)
Larger:
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))
Gives:
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)
As much patience as I have:
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))
Gives:
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)
The zip version and the itertuples version are within the confidence intervals each other. I suspect that they are doing the same thing under the hood.
These speed tests are probably irrelevant though. Pushing the limits of my computer's memory doesn't take a huge amount of time, and you really shouldn't be doing this on a large data set. Working with those tuples after doing this will end up being really inefficient. It's unlikely to be a major bottleneck in your code, so just stick with the version you think is most readable.
The most efficient and easy way:
list(data_set.to_records())
You can filter the columns you need before this call.
More pythonic way:
df = data_set[['data_date', 'data_1', 'data_2']]
map(tuple,df.values)
#try this one:
tuples = list(zip(data_set["data_date"], data_set["data_1"],data_set["data_2"]))
print (tuples)
참고URL : https://stackoverflow.com/questions/9758450/pandas-convert-dataframe-to-array-of-tuples
'program tip' 카테고리의 다른 글
내가 사용하는 Fedora 버전을 어떻게 찾을 수 있습니까? (0) | 2020.08.14 |
---|---|
Firefox는 selected = "selected"옵션을 무시합니다. (0) | 2020.08.14 |
iframe에서 스크롤바 제거 (0) | 2020.08.14 |
기본 인증이있는 경우 Node.js에서 http.client를 사용하는 방법 (0) | 2020.08.14 |
HTML 래퍼없이 DOMDocument의 HTML을 저장하는 방법은 무엇입니까? (0) | 2020.08.14 |