Как подсчитать отдельные поля из данного гибридного текстового файла csv / psv? - PullRequest
1 голос
/ 24 января 2020

Я считаю, Python - лучший выбор, но я могу ошибаться.

Ниже приведен пример из источника данных в текстовом формате Linux:

TUI,39832020:09:01,10.56| TUI,39832020:10:53,11.23| TUI,39832020:15:40,23.20
DIAN,39832020:09:04,11.56| TUI,39832020:11:45,11.23| DIAN,39832020:12:30,23.20| SLD,39832020:11:45,11.22

размер неизвестен, давайте предположим миллион строк.

Каждая строка содержит три или более наборов, разделенных |, и каждый набор имеет поля, разделенные ,.

Первое поле в каждый набор является идентификатором продукта. Например, в приведенном выше примере TUI, DIAN и SLD - это идентификаторы продуктов.

Мне нужно выяснить, сколько типов продуктов у меня в файле. Например, первая строка содержит 1: TUI, вторая строка содержит 3: DIAN, TUI и SLD.

Всего на этих двух строках мы можем видеть три уникальных продукта.

Кто-нибудь может помочь?

Большое спасибо. Любое просвещение приветствуется.

ОБНОВЛЕНИЕ

Я предпочитаю решение, основанное на Python с Spark, то есть pySpark.

Я также ищу для статистики, например:

  • общая сумма каждого продукта;
  • все записи за данное время (второе поле в каждом наборе, например 39832020:09:01);
  • минимальная и максимальная цена для каждого продукта.

ОБНОВЛЕНИЕ 2

Спасибо всем за код, я очень ценю. Интересно, может ли кто-нибудь записать данные в RDD и / или в фрейм данных? Я знаю, что в Spark SQL эту статистику очень просто получить.

Заранее большое спасибо.

Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 24 января 2020

Ваш CSV не очень стандартный, но мы можем обойти это:

import pandas as pd

# read rows of string
data = pd.read_csv("data.csv", delimiter='\n', header=None)

# split using pipe delimiter and expand to solve different row length
data = data[0].str.split('|', expand=True).replace(to_replace=[None], value='')

# keep only product type ID by removing what's after the first comma
data = data.apply(lambda x: x.map(lambda y: y.split(',')[0].strip()))

# count number of occurence of each product type ID per row
data.T.apply(pd.Series.value_counts)

Это дает количество вхождений каждого ID типа продукта в строке:

        0    1
      1.0  NaN
DIAN  NaN  2.0
SLD   NaN  1.0
TUI   3.0  1.0

Обратите внимание, что с точки зрения производительности, циклы и словари очень неэффективны, если ваш файл большой. Работа с библиотеками обработки данных, такими как pandas, лучше всего

0 голосов
/ 24 января 2020

Аналогично ответу Accdias: используйте словарь, читайте файл построчно, делите данные на |, затем на , и суммируйте значения в вашем словаре.

myFile="lines_to_read.txt"
productCounts = dict()

with open(myFile, 'r') as linesToRead:
    for thisLine in linesToRead:
        for myItem in thisLine.split("|"):
            productCode=myItem.split(",")
            productCode=productCode[0].strip()
            if productCode in productCounts:
                productCounts[productCode]+=1
            else:
                productCounts[productCode]=1

print(productCounts)

**** Обновить **** Dataframe использовать с Pandas, чтобы мы могли запрашивать статистику по последующим словам данных:

import pandas as pd

myFile="lines_to_read.txt"
myData = pd.DataFrame (columns=['prodID', 'timeStamp', 'prodPrice'])

with open(myFile, 'r') as linesToRead:
    for thisLine in linesToRead:
        for myItem in thisLine.split("|"):
            thisItem=myItem.strip('\n, " "').split(",")
            myData = myData.append({'prodID':thisItem[0],'timeStamp':thisItem[1],'prodPrice':thisItem[2]}, ignore_index=True)

print(myData)   # Full Table
print(myData.groupby('prodID').agg({'prodID':'count'}))  # Total of prodID's
print(myData.loc[myData['timeStamp'] == '39832020:11:45']) # all lines where time = 39832020:11:45
print(myData.groupby('prodID').agg({'prodPrice':['min', 'max']})) # min/max prices
...