Tôi đang xử lý Pandas DataFrame khá lớn - tập dữ liệu của tôi giống với df
thiết lập sau :
import pandas as pd
import numpy as np
#--------------------------------------------- SIZING PARAMETERS :
R1 = 20 # .repeat( repeats = R1 )
R2 = 10 # .repeat( repeats = R2 )
R3 = 541680 # .repeat( repeats = [ R3, R4 ] )
R4 = 576720 # .repeat( repeats = [ R3, R4 ] )
T = 55920 # .tile( , T)
A1 = np.arange( 0, 2708400, 100 ) # ~ 20x re-used
A2 = np.arange( 0, 2883600, 100 ) # ~ 20x re-used
#--------------------------------------------- DataFrame GENERATION :
df = pd.DataFrame.from_dict(
{ 'measurement_id': np.repeat( [0, 1], repeats = [ R3, R4 ] ),
'time':np.concatenate( [ np.repeat( A1, repeats = R1 ),
np.repeat( A2, repeats = R1 ) ] ),
'group': np.tile( np.repeat( [0, 1], repeats = R2 ), T ),
'object': np.tile( np.arange( 0, R1 ), T )
}
)
#--------------------------------------------- DataFrame RE-PROCESSING :
df = pd.concat( [ df,
df \
.groupby( ['measurement_id', 'time', 'group'] ) \
.apply( lambda x: np.random.uniform( 0, 100, 10 ) ) \
.explode() \
.astype( 'float' ) \
.to_frame( 'var' ) \
.reset_index( drop = True )
], axis = 1
)
Lưu ý: Với mục đích có một ví dụ tối thiểu, nó có thể dễ dàng được đặt lại (ví dụ với df.loc[df['time'] <= 400, :]
), nhưng vì tôi mô phỏng dữ liệu dù sao tôi nghĩ rằng kích thước ban đầu sẽ cho một cái nhìn tổng quan tốt hơn.
Đối với mỗi nhóm được xác định bởi ['measurement_id', 'time', 'group']
tôi cần gọi hàm sau:
from sklearn.cluster import SpectralClustering
from pandarallel import pandarallel
def cluster( x, index ):
if len( x ) >= 2:
data = np.asarray( x )[:, np.newaxis]
clustering = SpectralClustering( n_clusters = 5,
random_state = 42
).fit( data )
return pd.Series( clustering.labels_ + 1, index = index )
else:
return pd.Series( np.nan, index = index )
Để tăng cường hiệu suất, tôi đã thử hai cách tiếp cận:
Gói Pandarallel
Cách tiếp cận đầu tiên là song song hóa các tính toán bằng pandarallel
gói:
pandarallel.initialize( progress_bar = True )
df \
.groupby( ['measurement_id', 'time', 'group'] ) \
.parallel_apply( lambda x: cluster( x['var'], x['object'] ) )
Tuy nhiên, điều này có vẻ không tối ưu vì nó tiêu tốn rất nhiều RAM và không phải tất cả các lõi đều được sử dụng trong tính toán (ngay cả khi chỉ định rõ ràng số lượng lõi trong pandarallel.initialize()
phương thức). Ngoài ra, đôi khi các tính toán bị chấm dứt với các lỗi khác nhau, mặc dù tôi không có cơ hội tìm lý do cho điều đó (có thể là thiếu RAM?).
PandSpark Pandas UDF
Tôi cũng đã cho Spark Pandas UDF đi, mặc dù tôi hoàn toàn mới với Spark. Đây là nỗ lực của tôi:
import findspark; findspark.init()
from pyspark.sql import SparkSession
from pyspark.conf import SparkConf
from pyspark.sql.functions import pandas_udf, PandasUDFType
from pyspark.sql.types import *
spark = SparkSession.builder.master( "local" ).appName( "test" ).config( conf = SparkConf() ).getOrCreate()
df = spark.createDataFrame( df )
@pandas_udf( StructType( [StructField( 'id', IntegerType(), True )] ), functionType = PandasUDFType.GROUPED_MAP )
def cluster( df ):
if len( df['var'] ) >= 2:
data = np.asarray( df['var'] )[:, np.newaxis]
clustering = SpectralClustering( n_clusters = 5,
random_state = 42
).fit( data )
return pd.DataFrame( clustering.labels_ + 1,
index = df['object']
)
else:
return pd.DataFrame( np.nan,
index = df['object']
)
res = df \
.groupBy( ['id_half', 'frame', 'team_id'] ) \
.apply( cluster ) \
.toPandas()
Thật không may, hiệu năng cũng không đạt yêu cầu và từ những gì tôi đọc được về chủ đề này, đây có thể chỉ là gánh nặng của việc sử dụng hàm UDF, được viết bằng Python và nhu cầu liên quan đến việc chuyển đổi tất cả các đối tượng Python sang các đối tượng Spark và ngược lại.
Vì vậy, đây là những câu hỏi của tôi:
- Một trong những cách tiếp cận của tôi có thể được điều chỉnh để loại bỏ các tắc nghẽn có thể và cải thiện hiệu suất? (ví dụ: thiết lập PySpark, điều chỉnh các hoạt động phụ tối ưu, v.v.)
- Họ có bất kỳ lựa chọn thay thế tốt hơn? Làm thế nào để họ so sánh với các giải pháp được cung cấp về hiệu suất?
dask
((vì vậy nhận xét của tôi, đó chỉ là lời khuyên cho nghiên cứu.