簡體   English   中英

如何根據列索引列表從 pyspark 中的 csv 文件中選擇某些列,然后確定它們的不同長度

[英]How to select certain columns from a csv file in pyspark based on the list of index of columns and then determine their distinct lengths

我在pyspark中有此代碼,其中我將列的index值作為list傳遞。 現在我想從csv文件中為這些相應的索引選擇列:

def ml_test(input_col_index):

    sc = SparkContext(master='local', appName='test')

    inputData = sc.textFile('hdfs://localhost:/dir1').zipWithIndex().filter(lambda (line, rownum): rownum >= 0).map(lambda (line, rownum): line)

if __name__ == '__main__':

    input_col_index = sys.argv[1] # For example - ['1','2','3','4']

    ml_test(input_col_index)

現在,如果我想從上面的csv文件中選擇一組靜態或硬編碼的列,我可以這樣做,但這里所需列的indexes作為參數傳遞。 此外,我必須計算每個選定列的不同長度,我知道這可以通過colmn_1 = input_data.map(lambda x: x[0]).distinct().collect()但我如何為一組未知的列,是根據運行時傳遞的索引列表確定的?

注意:我必須計算列的不同長度,因為我必須將該長度作為參數傳遞給Pysparks RandomForest算法。

您可以使用列表推導式。

# given a list of indicies...
indicies = [int(i) for i in input_col_index]

# select only those columns from each row
rdd = rdd.map(lambda x: [x[idx] for idx in indicies])

# for all rows, choose longest columns
longest_per_column = rdd.reduce(
    lambda x, y: [max(a, b, key=len) for a, b in zip(x, y)])

# get lengths of longest columns
print([len(x) for x in longest_per_column])

減少函數采用兩個列表,同時循環遍歷它們的每個值,並通過選擇(對於每一列)較長的一個來創建一個新列表。

更新:要將長度傳遞給RandomForest構造函數,您可以執行以下操作:

column_lengths = [len(x) for x in longest_per_column]

model = RandomForest.trainRegressor(
    categoricalFeaturesInfo=dict(enumerate(column_lengths)),
    maxBins=max(column_lengths),
    # ...
)

我會推薦這個簡單的解決方案。

假設我們有以下 CSV 文件結構 [1]:

"TRIP_ID","CALL_TYPE","ORIGIN_CALL","ORIGIN_STAND","TAXI_ID","TIMESTAMP","DAY_TYPE","MISSING_DATA","POLYLINE"
"1372636858620000589","C","","","20000589","1372636858","A","False","[[-8.618643,41.141412],[-8.618499,41.141376]]"

並且您只想選擇列: CALL_TYPE, TIMESTAMP, POLYLINE首先您需要格式化數據,然后拆分並選擇您需要的列。 這很簡單:

from pyspark import SparkFiles
raw_data = sc.textFile("data.csv")
callType_days = raw_data.map(lambda x: x.replace('""','"NA"').replace('","', '\n').replace('"','')) \
    .map(lambda x: x.split()) \
    .map(lambda x: (x[1],x[5],x[8]))

callType_days.take(2)

結果將是:

[(u'CALL_TYPE', u'TIMESTAMP', u'POLYLINE'),
 (u'C',
  u'1372636858',
  u'[[-8.618643,41.141412],[-8.618499,41.141376]]')]

之后,處理這樣的結構化數據真的很容易。

[1]: 出租車服務軌跡 - 預測挑戰,ECML PKDD 2015 數據集

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM