Nano Hash - криптовалюты, майнинг, программирование

Использование Pandas для рекурсивного объединения файлов CSV в каталоге

Вот ссылка из предыдущего поста. . Я цитирую ответ PR ниже.

 import pandas as pd
    import glob
    interesting_files = glob.glob("*.csv")
    df_list = []
    for filename in sorted(interesting_files):
        df_list.append(pd.read_csv(filename))
    full_df = pd.concat(df_list)

    full_df.to_csv('output.csv')

Мне интересно, как изменить вышеизложенное, используя pandas. В частности, я пытаюсь рекурсивно перемещаться по каталогу и объединять все заголовки CSV и их соответствующие значения строк, а затем записывать их в один файл. Использование подхода P.R приводит к тому, что все заголовки и соответствующие им значения накладываются друг на друга. Мои ограничения:

  • Запись заголовков и соответствующих им значений (без "укладки") - по существу конкатенация один за другим

  • Если заголовки столбцов в одном файле совпадают с другими файлами, то они не должны повторяться. Добавлять следует только значения, поскольку они записываются в один CSV-файл.

  • Поскольку каждый файл имеет разные заголовки столбцов и разное количество заголовков столбцов, все они должны быть добавлены. Ничего не должно быть удалено.

Я также пробовал следующее:

import pandas as pd
import csv
import glob
import os

path = '.'
files_in_dir = [f for f in os.listdir(path) if f.endswith('csv')]

for filenames in files_in_dir:
    df = pd.read_csv(filenames)
    df.to_csv('out.csv', mode='a')

Вот два примера CSV:

ID,Type,ACH,SH,LL,SS,LS,ISO,MID,Pass,TID,CID,TErrors
12821767,Query,,,,,,,,,,,

и

Type,ID,CC,CCD,Message,MemberIdentifier,NPass,UHB,UAP,NewAudioPIN,AType,ASuufix,Member,Share,Note,Flag,Card,MA,Preference,ETF,AutoT,RType,Locator,ISO,MID,Pass,TID,CID,Errors
UMember,12822909,True,10/31/2013 5:22:19 AM,,,,False,False,,,,,,,,,,,,,Member,,,,,,,

Основываясь на приведенном выше примере, вывод должен быть примерно таким:

    ID,Type,ACH,SH,LL,SS,LS,ISO,MID,Pass,TID,CID,TErrors,CC,CCD,Message,MemberIdentifier,NPass,UHB,UAP,NewAudioPIN,AType,ASuufix,Member,Share,Note,Flag,Card,MA,Preference,ETF,AutoT,RType,Locator,Errors
12822909,UMember,,,,,,,,,,,,True,10/31/2013 5:22:19 AM,,,,False,False,,,,,,,,,,,,,Member,,
12821767,Query ,,,,,,,,,,,,,,,,,,,,,,,,, etc.

(все столбцы заголовков во втором примере должны быть заполнены разделителем ',' для второй строки, где нет соответствующего заголовка в первом примере)

Как видно, во втором примере больше заголовков столбцов. Более того, некоторые из заголовков одинаковы (но в другом порядке). Я пытаюсь объединить все это вместе с их значениями, следуя вышеуказанным требованиям. Мне интересно, лучший ли метод — объединить или выполнить настраиваемую функцию встроенного метода панд?


  • Для примера, который вы разместили, каков желаемый результат? 09.07.2015
  • Есть ли какая-то конкретная причина, по которой вы хотите использовать здесь pandas - я думаю, без этого было бы проще... (интересное новое имя @HappyLeapSecond!) 09.07.2015
  • @HappyLeapSecond Я попытался прояснить это с помощью маркеров - это довольно сложно объяснить, не рисуя. Все заголовки должны быть в одной строке/строке, а значения в следующей строке. Общие заголовки не должны повторяться, но значения должны добавляться в соответствии с каждым заголовком. Порядок должен поддерживаться, и ни один заголовок или значение не должны быть удалены. Любые новые заголовки должны добавляться автоматически (вместе со значением). 09.07.2015
  • @JonClements Я думал, что панды будут самым эффективным методом. Если у вас есть альтернативное предложение, я приветствую ваши мысли. 09.07.2015
  • @ 890319ahlusar есть ли только одна строка данных для каждого CSV-файла? 09.07.2015
  • @JonClements Да. Одна строка для заголовков и одна строка для данных 09.07.2015
  • Будет ли цикл while работать лучше, чем рекурсия? 24.02.2017

Ответы:


1

Подход, не основанный на pandas, в котором используются модули OrderedDict и csv.

from glob import iglob
import csv
from collections import OrderedDict

files = sorted(iglob('*.csv'))
header = OrderedDict()
data = []
for filename in files:
    with open(filename, 'rb') as fin:
        csvin = csv.DictReader(fin)
        try:
            header.update(OrderedDict.fromkeys(csvin.fieldnames))
            data.append(next(csvin))
        except TypeError:
            print filename, 'was empty'
        except StopIteration:
            print filename, "didn't contain a row"

with open('output_filename.csv', 'wb') as fout:
    csvout = csv.DictWriter(fout, fieldnames=list(header))
    csvout.writeheader()
    csvout.writerows(data)

Учитывая ваш пример ввода, это дает вам:

ID,Type,ACH,SH,LL,SS,LS,ISO,MID,Pass,TID,CID,TErrors,CC,CCD,Message,MemberIdentifier,NPass,UHB,UAP,NewAudioPIN,AType,ASuufix,Member,Share,Note,Flag,Card,MA,Preference,ETF,AutoT,RType,Locator,Errors
12821767,Query,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
12822909,UMember,,,,,,,,,,,,True,10/31/2013 5:22:19 AM,,,,False,False,,,,,,,,,,,,,Member,,
09.07.2015
  • У меня было очень похожее решение для вашего вышеприведенного подхода, отличного от Pandas. Предостережение заключается в том, что все имена ключей/столбцов, которые повторяются в других CSV-файлах (и имеют разные соответствующие значения строк), не добавляются последовательно. Например, в приведенных выше двух примерах есть два разных значения для заголовка столбца Type: UMember и Query. В идеале Query должен быть добавлен после UMember. Если есть другие подобные заголовки столбцов, то их значения должны подчиняться тому же правилу. Остальные требования по-прежнему контролируются. 10.07.2015
  • @ 890319ahlusar, вам действительно придется потратить несколько минут, чтобы обновить свой вопрос, указав точный ожидаемый результат из ваших входных примеров, тогда ... 10.07.2015
  • Я сделаю это как можно скорее @JonClements 10.07.2015
  • @ 890319ahlusar пришлось выскочить - обновлено в соответствии с вашими требованиями ... 10.07.2015
  • @ 890319ahlusar расскажет, что это за ошибка? :п 10.07.2015
  • Я получаю следующую ошибку (еще раз спасибо за ваш отзыв): ---------------------------------- ------------------------------------------------------- TypeError Traceback (самый последний вызов последним) - --› 11 header.update(OrderedDict.fromkeys(csvin.fieldnames)) 12 data.append(next(csvin)) init.py в fromkeys(cls, iterable, value) 220 ''' 221 self = cls() --> 222 для ключа в итерируемом: 223 self[key] = значение 224 return self TypeError: объект 'NoneType' не является итерируемым 10.07.2015
  • @ 890319ahlusar, значит, у тебя, наверное, пустой файл? 10.07.2015
  • @ 890319ahlusar завернул его в попытку, за исключением того, что вы можете видеть, пуст ли файл или он содержит только заголовки 10.07.2015
  • Вы правы @JonClements - один из 1134 файлов был пуст! Ваше здоровье! 10.07.2015

  • 2

    В pandas вы можете легко добавлять имена столбцов и изменять порядок фрейма данных. См. эту статью о слиянии фреймов.

    Чтобы добавить кадры и изменить их порядок, вы можете использовать следующее. Переиндексация так же проста, как использование списка. Есть больше решений здесь.

    import pandas,os
    
    df = None
    dfList=[]
    for filename in [directory+x for x in os.listdir(path)]:
        dfList.append(pd.read_csv(filename))
    df=pandas.concat(dfList)
    df.to_csv('out.csv', mode='w')
    

    С пониманием списка это будет:

    import pandas,os    
    pandas.concat([pd.read_csv(filename) for filename in [directory+x for x in os.listdir(path) if x.endswith("csv") is True]]).to_csv('out.csv', mode='w')
    

    Если вы хотите переиндексировать что-либо, просто используйте список.

    cols=sorted(list(df.columns.values))
    df=df[cols]
    #or
    df=df[sorted(list(df.columns.values))]
    
    09.07.2015
  • Было бы более эффективно читать df из каждого csv в список, а затем объединять все df в списке, а не объединять каждый. 09.07.2015
  • @EdChum - Можно ли привести пример? 09.07.2015
  • @ 890319ahlusar, читая статью, также объяснит более сложные функции, но concat должен охватывать все. 09.07.2015
  • @AndrewScottEvans Спасибо за справочные материалы. Я внимательно изучил их. Однако оказывается, что одновременно можно объединить только два фрейма данных. Есть ли подфункция, которую вы бы порекомендовали, которая позволяет мне проверять те же заголовки, а затем добавлять соответствующее значение этого заголовка, если проверка верна? Хочу разобраться в недрах панд :) 09.07.2015
  • @ 890319ahlusar Добавьте их в список, например pandas.concat([df1,df2,df3]). Лучший пример с места в карьер — ‹a href=stackoverflow .com/questions/15819050/› этот пост‹/a›. Я только что видел код. Это также касается добавления v. concat. 10.07.2015
  • @AndrewScottEvans Я попытался сделать это по вашему предложению - это работает! Ваше здоровье! 14.07.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..