เชฒเซเชเชจเซ เช
เชจเซเชตเชพเชฆ เชเซเชฐเซเชธเชจเชพ เชตเชฟเชฆเซเชฏเชพเชฐเซเชฅเซเช เชฎเชพเชเซ เชเชพเชธ เชคเซเชฏเชพเชฐ เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฏเซ เชนเชคเซ
เชเซเชฒเซเชฒเชพ เชเซเชเชฒเชพเช เช
เช เชตเชพเชกเชฟเชฏเชพเชฎเชพเช เช
เชฎเชพเชฐเซ เชชเชพเชธเซ เชเซ
เชธเซเชเซเชฐเซเชฎเชฟเชเช เชเซเชฒเชฎ เชกเซเชเชพ
เชเชฐเซ เชฏเซเชเชฐเซเชธ เชคเชฐเชซเชฅเซ เชฎเชจเซ เชฎเชณเซเชฒเซ เชเช เชธเชพเชฎเชพเชจเซเชฏ เชชเซเชฐเชถเซเชจ เช เชชเชเชเซเชคเชฟ- เช เชฅเชตเชพ เชฐเซเชเซเชฐเซเชก-เชเชฐเชฟเชเชจเซเชเซเชก เชซเซเชฐเซเชฎเซเชเชฎเชพเชเชฅเซ เชเซเชฒเชฎ-เชเชฐเชฟเชเชจเซเชเซเชก เชซเซเชฐเซเชฎเซเชเชฎเชพเช เชเซเชฌเซเชฏเซเชฒเชฐ เชกเซเชเชพเชจเชพ เชฎเซเชเชพ เชธเซเชเชจเซ เชธเซเชฅเชพเชจเชพเชเชคเชฐเชฟเชค เชเชฐเชตเชพเชจเซ เชเชเชเซ เชเชฟเชเชฎเชค เชเซ. เชฎเชฒเซเชเซ-เชเซเชเชพเชฌเชพเชเช เชกเซเชเชพเชธเซเชเซเชธ เชฎเชพเชเซ, เชฎเซเชฎเชฐเซเชฎเชพเช เช เชฅเชตเชพ เชกเชฟเชธเซเช เชชเชฐ เชธเซเชฅเชพเชจเชพเชเชคเชฐเชฟเชค เชเชฐเชตเซเช เช เชเชฌเชฐเชเชธเซเชค เชเชพเชฐเซเชฏ เชนเซเช เชถเชเซ เชเซ.
เชกเซเชเชพเชจเซ เชธเซเชเซเชฐเซเชฎ เชเชฐเชตเชพ เชฎเชพเชเซ, เชญเชฒเซ เชธเซเชฐเซเชค เชกเซเชเชพ เชชเชเชเซเชคเชฟ เชนเซเชฏ เชเซ เชเซเชฒเชฎ, เชเช เชตเชฟเชเชฒเซเชช เช เชเซ เชเซ เชชเชเชเซเชคเชฟเชเชจเชพ เชจเชพเชจเชพ เชฌเซ เชเซเชธ เชฎเซเชเชฒเซ, เชเซเชฎเชพเช เชฆเชฐเซเช เช เชเชฆเชฐ เชธเซเชคเชเชญเชพเชเชพเชฐ เชฒเซเชเชเช เชงเชฐเชพเชตเซ เชเซ.
เช เชชเชพเชเซ เชเชฐเซเชฎเชพเช, เชเซเชฌเชฒเชจเชพ เชญเชพเชเชจเซเช เชชเซเชฐเชคเชฟเชจเชฟเชงเชฟเชคเซเชต เชเชฐเชคเซ เชเชจ-เชฎเซเชฎเชฐเซ เชเซเชฒเชฎ เชเชฐเซเชจเชพ เชธเชเชเซเชฐเชนเชจเซ เชฐเซเชเซเชฐเซเชก เชฌเซเช เชเชนเซเชตเชพเชฎเชพเช เชเชตเซ เชเซ. เชฒเซเชเชฟเชเชฒ เชเซเชฌเชฒเชจเชพ เชเช เชกเซเชเชพ เชธเซเชเซเชฐเชเซเชเชฐเชจเซเช เชชเซเชฐเชคเชฟเชจเชฟเชงเชฟเชคเซเชต เชเชฐเชตเชพ เชฎเชพเชเซ, เชฐเซเชเซเชฐเซเชกเชจเซ เชเชฃเซ เชฌเซเช เชเชเชคเซเชฐเชฟเชค เชเชฐเซ เชถเชเชพเชฏ เชเซ.
เชนเชพเชฒเชจเชพ "เชฐเซเชจเซเชกเชฎ เชเชเซเชธเซเชธ" เชซเชพเชเชฒ เชซเซเชฐเซเชฎเซเชเชฎเชพเช, เช เชฎเซ เชฎเซเชเชพเชกเซเชเชพเชจเซ เชฐเซเชเซเชฐเซเชก เชเชฐเซเช เชเซเช เชเซเชฎเชพเช เชเซเชฌเชฒ เชธเซเชเซเชฎเชพ เชนเซเชฏ เชเซ เช เชจเซ เชซเชพเชเชฒเชจเชพ เช เชเชคเซ เชฌเซเชฒเซเช เชธเซเชฅเชพเชจเซ เชนเซเชฏ เชเซ, เชเซเชจเชพเชฅเซ เชคเชฎเซ เชกเซเชเชพ เชธเซเชเชฎเชพเชเชฅเซ เชฐเซเชเซเชฐเซเชกเชจเชพ เชเซเชเชชเชฃ เชฌเซเช เช เชฅเชตเชพ เชเซเชเชชเชฃ เชเซเชฒเชฎเชจเซ เช เชคเซเชฏเชเชค เชธเชธเซเชคเชพเชฎเชพเช เชชเชธเชเชฆ เชเชฐเซ เชถเชเซ เชเซ. เชธเซเชเซเชฐเซเชฎเชฟเชเช เชซเซเชฐเซเชฎเซเชเชฎเชพเช, เช เชฎเซ เชธเชเชฆเซเชถเชพเชเชจเซ เชถเซเชฐเซเชฃเซ เชฎเซเชเชฒเซเช เชเซเช: เชเช เชฐเซเชชเชฐเซเชเชพ, เช เชจเซ เชชเชเซ เชฐเซเชเซเชฐเซเชกเชจเซ เชเช เช เชฅเชตเชพ เชตเชงเซ เชฌเซเช.
เชตเชฟเชตเชฟเชง เชซเซเชฐเซเชฎเซเชเซเชธ เชเชเชเช เชเชจเชพ เชเซเชตเชพ เชฆเซเชเชพเชฏ เชเซ:
PyArrow เชฎเชพเช เชธเซเชเซเชฐเซเชฎเชฟเชเช เชกเซเชเชพ: เชเชชเซเชฒเชฟเชเซเชถเชจ
เช เชเซเชตเซ เชฐเซเชคเซ เชเชพเชฐเซเชฏ เชเชฐเซ เชเซ เชคเซ เชฌเชคเชพเชตเชตเชพ เชฎเชพเชเซ, เชนเซเช เชเช เชธเซเชเซเชฐเซเชฎ เชญเชพเชเชจเซเช เชชเซเชฐเชคเชฟเชจเชฟเชงเชฟเชคเซเชต เชเชฐเชคเซเช เชเชฆเชพเชนเชฐเชฃ เชกเซเชเชพเชธเซเช เชฌเชจเชพเชตเซเชถ:
import time
import numpy as np
import pandas as pd
import pyarrow as pa
def generate_data(total_size, ncols):
nrows = int(total_size / ncols / np.dtype('float64').itemsize)
return pd.DataFrame({
'c' + str(i): np.random.randn(nrows)
for i in range(ncols)
})
เชนเชตเซ, เชเชพเชฒเซ เชเชนเซเช เชเซ เชเชชเชฃเซ เชเซเชฒ 1 เชนเชฟเชธเซเชธเชพ เชฎเชพเชเซ 1 GB เชกเซเชเชพ เชฒเชเชตเชพ เชฎเชพเชเชเซเช เชเซเช, เชเซเชฎเชพเช 1024 MB เชฆเชฐเซเช เชนเชฟเชธเซเชธเชพเชจเซ เชธเชฎเชพเชตเซเชถ เชฅเชพเชฏ เชเซ. เชถเชฐเซ เชเชฐเชตเชพ เชฎเชพเชเซ, เชเชพเชฒเซ 1 เชเซเชฒเชฎ เชธเชพเชฅเซ เชชเซเชฐเชฅเชฎ 16 MB เชกเซเชเชพ เชซเซเชฐเซเชฎ เชฌเชจเชพเชตเซเช:
KILOBYTE = 1 << 10
MEGABYTE = KILOBYTE * KILOBYTE
DATA_SIZE = 1024 * MEGABYTE
NCOLS = 16
df = generate_data(MEGABYTE, NCOLS)
เชชเชเซ เชนเซเช เชคเซเชฎเชจเซ เชเชจเซเชตเชฐเซเช เชเชฐเซเช เชเซเช pyarrow.RecordBatch
:
batch = pa.RecordBatch.from_pandas(df)
เชนเชตเซ เชนเซเช เชเช เชเชเชเชชเซเช เชธเซเชเซเชฐเซเชฎ เชฌเชจเชพเชตเซเชถ เชเซ RAM เชชเชฐ เชฒเชเชถเซ เช
เชจเซ เชฌเชจเชพเชตเชถเซ StreamWriter
:
sink = pa.InMemoryOutputStream()
stream_writer = pa.StreamWriter(sink, batch.schema)
เชชเชเซ เช เชฎเซ 1024 เชนเชฟเชธเซเชธเชพเช เชฒเชเซเชถเซเช, เชเซ เชเชเชฐเซ 1GB เชกเซเชเชพ เชธเซเชเชจเซ เชฐเชเชฎ เชนเชถเซ:
for i in range(DATA_SIZE // MEGABYTE):
stream_writer.write_batch(batch)
เช เชฎเซ RAM เชจเซ เชฒเชเซเชฏเซเช เชนเซเชตเชพเชฅเซ, เช เชฎเซ เชธเชฎเชเซเชฐ เชธเซเชเซเชฐเซเชฎเชจเซ เชเช เชฌเชซเชฐเชฎเชพเช เชฎเซเชณเชตเซ เชถเชเซเช เชเซเช:
In [13]: source = sink.get_result()
In [14]: source
Out[14]: <pyarrow.io.Buffer at 0x7f2df7118f80>
In [15]: source.size
Out[15]: 1074750744
เช เชกเซเชเชพ เชฎเซเชฎเชฐเซเชฎเชพเช เชนเซเชตเชพเชฅเซ, เชเชฐเซ เชฐเซเชเซเชฐเซเชกเชจเซ เชฌเซเช เชตเชพเชเชเชตเซ เช เชถเซเชจเซเชฏ-เชเซเชชเซ เชเชพเชฎเชเซเชฐเซ เชเซ. เชนเซเช StreamReader เชเซเชฒเซเช เชเซเช, เชคเซเชฎเชพเช เชกเซเชเชพ เชตเชพเชเชเซเช เชเซเช pyarrow.Table
, เช
เชจเซ เชชเชเซ เชคเซเชฎเชจเซ เชเชจเซเชตเชฐเซเช เชเชฐเซ DataFrame pandas
:
In [16]: reader = pa.StreamReader(source)
In [17]: table = reader.read_all()
In [18]: table
Out[18]: <pyarrow.table.Table at 0x7fae8281f6f0>
In [19]: df = table.to_pandas()
In [20]: df.memory_usage().sum()
Out[20]: 1073741904
เช เชฌเชงเซเช, เช เชฒเชฌเชคเซเชค, เชธเชพเชฐเซเช เชเซ, เชชเชฐเชเชคเซ เชคเชฎเชจเซ เชชเซเชฐเชถเซเชจเซ เชนเซเช เชถเชเซ เชเซ. เช เชเซเชเชฒเซ เชเชกเชชเชฅเซ เชฅเชพเชฏ เชเซ? เชญเชพเชเชจเซเช เชเชฆ เชชเชพเชเชกเชพ เชกเซเชเชพเชซเซเชฐเซเชฎ เชชเซเชจเชเชชเซเชฐเชพเชชเซเชคเชฟ เชเชพเชฎเชเซเชฐเซเชจเซ เชเซเชตเซ เชฐเซเชคเซ เช เชธเชฐ เชเชฐเซ เชเซ?
เชธเซเชเซเชฐเซเชฎเชฟเชเช เชชเซเชฐเชฆเชฐเซเชถเชจ
เชเซเชฎ เชเซเชฎ เชธเซเชเซเชฐเซเชฎเชฟเชเช เชเชเชเชจเซเช เชเชฆ เชเชเชคเซเช เชเชพเชฏ เชเซ เชคเซเชฎ, เช เชฏเซเชเซเชฏ เชเซเชถ เชเชเซเชธเซเชธ เชชเซเชเชฐเซเชจเชจเซ เชเชพเชฐเชฃเซ เชชเชพเชเชกเชพเชฎเชพเช เชธเชเชฒเชเซเชจ เชธเซเชคเชเชญเชพเชเชพเชฐ เชกเซเชเชพเชซเซเชฐเซเชฎเชจเซเช เชชเซเชจเชฐเซเชจเชฟเชฐเซเชฎเชพเชฃ เชเชฐเชตเชพเชจเซ เชเชฟเชเชฎเชค เชตเชงเซ เชเซ. C++ เชกเซเชเชพ เชธเซเชเซเชฐเชเซเชเชฐเซเชธ เช เชจเซ เชเชฐเซ เช เชจเซ เชคเซเชฎเชจเชพ เชฎเซเชฎเชฐเซ เชฌเชซเชฐเซเชธ เชธเชพเชฅเซ เชเชพเชฎ เชเชฐเชตเชพเชฅเซ เชเซเชเชฒเชพเช เชเชตเชฐเชนเซเชก เชชเชฃ เชเซ.
1 MB เชฎเชพเชเซ, เชเชชเชฐ เชฎเซเชเชฌ, เชฎเชพเชฐเชพ เชฒเซเชชเชเซเชช (เชเซเชตเชพเชก-เชเซเชฐ Xeon E3-1505M) เชชเชฐ เชคเซ เชคเชพเชฐเชฃ เชเชชเซ เชเซ:
In [20]: %timeit pa.StreamReader(source).read_all().to_pandas()
10 loops, best of 3: 129 ms per loop
เชคเซ เชคเชพเชฐเชฃ เชเชชเซ เชเซ เชเซ 7.75 1MB เชนเชฟเชธเซเชธเชพเชฎเชพเชเชฅเซ 1024GB เชกเซเชเชพเชซเซเชฐเซเชฎ เชชเซเชจเชเชธเซเชฅเชพเชชเชฟเชค เชเชฐเชตเชพ เชฎเชพเชเซ เช เชธเชฐเชเชพเชฐเช เชฅเซเชฐเซเชชเซเช 1 GB/s เชเซ. เชเซ เชเชชเชฃเซ เชฎเซเชเชพ เช เชฅเชตเชพ เชจเชพเชจเชพ เชญเชพเชเซเชจเซ เชเชชเชฏเซเช เชเชฐเซเช เชคเซ เชถเซเช เชฅเชพเชฏ เชเซ? เช เชชเชฐเชฟเชฃเชพเชฎเซ เชเซ:
เชเชพเชฎเชเซเชฐเซ เชจเซเชเชงเชชเชพเชคเซเชฐ เชฐเซเชคเซ 256K เชฅเซ 64K เชนเชฟเชธเซเชธเชพเชฎเชพเช เชเชเซ เชเซ. เชฎเชจเซ เชเชถเซเชเชฐเซเชฏ เชฅเชฏเซเช เชเซ 1 MB เชนเชฟเชธเซเชธเชพ เชชเชฐ 16 MB เชนเชฟเชธเซเชธเชพ เชเชฐเชคเชพเช เชตเชงเซ เชเชกเชชเชฅเซ เชชเซเชฐเชเซเชฐเชฟเชฏเชพ เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชนเชคเซ. เชตเชงเซ เชเชเชกเชพเชฃเชชเซเชฐเซเชตเช เช
เชญเซเชฏเชพเชธ เชเชฐเชตเชพ เช
เชจเซ เชธเชฎเชเชตเชพ เชฏเซเชเซเชฏ เชเซ เชเซ เชถเซเช เช เชเช เชธเชพเชฎเชพเชจเซเชฏ เชตเชฟเชคเชฐเชฃ เชเซ เชเซ เชชเชเซ เชเชเชเช เชฌเซเชเซเช เชเซ.
เชซเซเชฐเซเชฎเซเชเชจเชพ เชตเชฐเซเชคเชฎเชพเชจ เช เชฎเชฒเซเชเชฐเชฃเชฎเชพเช, เชกเซเชเชพ เชธเซเชฆเซเชงเชพเชเชคเชฟเช เชฐเซเชคเซ เชธเชเชเซเชเชฟเชค เชจเชฅเซ, เชคเซเชฅเซ เชฎเซเชฎเชฐเซเชฎเชพเช เชเชฆ เช เชจเซ "เชตเชพเชฏเชฐเซเชฎเชพเช" เชฒเชเชญเช เชธเชฎเชพเชจ เชเซ. เชญเชตเชฟเชทเซเชฏเชฎเชพเช, เชเชฎเซเชชเซเชฐเซเชถเชจ เชเช เชตเชงเชพเชฐเชพเชจเซ เชตเชฟเชเชฒเซเชช เชฌเชจเซ เชถเชเซ เชเซ.
เชชเชฐเชฟเชฃเชพเชฎ
เชเซเชฒเชฎเชฐ เชกเซเชเชพ เชธเซเชเซเชฐเซเชฎเชฟเชเช เช เชฎเซเชเชพ เชกเซเชเชพ เชธเซเชเซเชธเชจเซ เชเซเชฒเชฎเชฐ เชเชจเชพเชฒเชฟเชเชฟเชเซเชธ เชเซเชฒเซเชธเชฎเชพเช เชซเซเชก เชเชฐเชตเชพเชจเซ เช เชธเชฐเชเชพเชฐเช เชฐเซเชค เชนเซเช เชถเชเซ เชเซ เชเซเชฎ เชเซ เชจเชพเชจเชพ เชญเชพเชเซเชฎเชพเช เชชเชพเชเชกเชพ. เชกเซเชเชพ เชธเซเชตเชพเช เชเซ เชเซ เชชเชเชเซเชคเชฟ-เชเชฐเชฟเชเชจเซเชเซเชก เชธเซเชเซเชฐเซเชเชจเซ เชเชชเชฏเซเช เชเชฐเซ เชเซ เชคเซ เชคเชฎเชพเชฐเชพ เชชเซเชฐเซเชธเซเชธเชฐเชจเชพ L2 เช เชจเซ L3 เชเซเชถ เชฎเชพเชเซ เชตเชงเซ เช เชจเซเชเซเชณ เชเชตเชพ เชกเซเชเชพเชจเชพ เชจเชพเชจเชพ เชนเชฟเชธเซเชธเชพเชจเซ เชเซเชฐเชพเชจเซเชธเชซเชฐ เช เชจเซ เชเซเชฐเชพเชจเซเชธเชชเซเช เชเชฐเซ เชถเชเซ เชเซ.
เชธเชเชชเซเชฐเซเชฃ เชเซเชก
import time
import numpy as np
import pandas as pd
import pyarrow as pa
def generate_data(total_size, ncols):
nrows = total_size / ncols / np.dtype('float64').itemsize
return pd.DataFrame({
'c' + str(i): np.random.randn(nrows)
for i in range(ncols)
})
KILOBYTE = 1 << 10
MEGABYTE = KILOBYTE * KILOBYTE
DATA_SIZE = 1024 * MEGABYTE
NCOLS = 16
def get_timing(f, niter):
start = time.clock_gettime(time.CLOCK_REALTIME)
for i in range(niter):
f()
return (time.clock_gettime(time.CLOCK_REALTIME) - start) / NITER
def read_as_dataframe(klass, source):
reader = klass(source)
table = reader.read_all()
return table.to_pandas()
NITER = 5
results = []
CHUNKSIZES = [16 * KILOBYTE, 64 * KILOBYTE, 256 * KILOBYTE, MEGABYTE, 16 * MEGABYTE]
for chunksize in CHUNKSIZES:
nchunks = DATA_SIZE // chunksize
batch = pa.RecordBatch.from_pandas(generate_data(chunksize, NCOLS))
sink = pa.InMemoryOutputStream()
stream_writer = pa.StreamWriter(sink, batch.schema)
for i in range(nchunks):
stream_writer.write_batch(batch)
source = sink.get_result()
elapsed = get_timing(lambda: read_as_dataframe(pa.StreamReader, source), NITER)
result = (chunksize, elapsed)
print(result)
results.append(result)
เชธเซเชฐเซเชธ: www.habr.com