Python l oop через список CSV и проверить значение? - PullRequest
2 голосов
/ 29 мая 2020

У меня есть пять .csv с одинаковыми полями в том же порядке, которые необходимо обрабатывать как таковые:

  • Получить список файлов
  • Сделать каждый файл в фрейм данных
  • Проверьте, имеет ли столбец комбинаций букв и цифр заданное c значение (разное для каждого файла), например: проверьте, находится ли число PT333 в column1 для имени файла data1:
column1   column2    column3    
PT389     LA       image.jpg
PT372     NY       image2.jpg
  • Если столбец имеет определенное значение c, выведите его значение и имя файла / переменной, которые я назначил этому файлу, и затем переименуйте этот фрейм данных в output1

Я пытался сделать это, но не знаю, как сделать его l oop и сделать то же самое для каждого файла. На данный момент он возвращает номер, но я также хочу, чтобы он возвращал имя фрейма данных, и я также хочу, чтобы он равнялся l oop во всех файлах (от a до e), чтобы проверить все значения в numbers list.

Вот что у меня есть:

import os
import glob
import pandas as pd
from glob import glob
from os.path import expanduser

home = expanduser("~")
os.chdir(home + f'/files/')

data = glob.glob('data*.csv')
data

# If you have tips on how to loop through these rather than 
# have a line for each one, open to feedback
a = pd.read_csv(data[0], encoding='ISO-8859-1', error_bad_lines=False)
b = pd.read_csv(data[1], encoding='ISO-8859-1', error_bad_lines=False)
c = pd.read_csv(data[2], encoding='ISO-8859-1', error_bad_lines=False)
d = pd.read_csv(data[3], encoding='ISO-8859-1', error_bad_lines=False)
e = pd.read_csv(data[4], encoding='ISO-8859-1', error_bad_lines=False)
filenames = [a,b,c,d,e]
filelist= ['a','b','c','d','e']

# I am aware that this part is repetitive. Unsure how to fix this,
# I keep getting errors
# Any help appreciated
numbers = ['PT333', 'PT121', 'PT111', 'PT211', 'PT222']
def type():
    for i in a.column1:
        if i == numbers[0]:
            print(numbers[0])
        elif i == numbers[1]:
            print(numbers[1])
        elif i == numbers[2]:
            print(numbers[2])
        elif i == numbers[3]:
            print(numbers[3])
        elif i == numbers[4]:
            print(numbers[4])
type()

Также рад принять любую конструктивную критику относительно того, как повторять меньше кода и делать вещи более гладкими. TIA

Ответы [ 3 ]

1 голос
/ 29 мая 2020

Также рад принять любую конструктивную критику относительно того, как можно меньше повторять код и сделать его более гладким.

Надеюсь, вы не возражаете, что я начал с реструктуризации кода. это упрощает объяснение следующих шагов

загрузка массива файлов

Использование построителя списков позволяет нам перебирать файлы и загружать их в список в 1 строку. Он также имеет много памяти и времени.

files = [pd.read_csv(entry, encoding='ISO-8859-1', error_bad_lines=False) for entry in data]

подробнее о понимании

Тип Функция

Сначала нам нужен аргумент, чтобы мы можем вызвать эту функцию для любого заданного файла. Наряду со списком мы можем l oop поверх него с a для каждого l oop.

Вызов функции типа для нескольких файлов

Здесь мы снова используем для каждого цикла

for file in files:
    type(file)

подробнее python для шлейфов


def type(file):
    for value in file.column1:
        if value in numbers:
            print(value)

Результат


import os
import glob
import pandas as pd
from glob import glob
from os.path import expanduser

home = expanduser("~")
os.chdir(home + f'/files/')

#please note that i am use glob instead of glob.glob here.
data = glob('data*.csv')
files = [pd.read_csv(entry, encoding='ISO-8859-1', error_bad_lines=False) for entry in data]


numbers = ['PT333', 'PT121', 'PT111', 'PT211', 'PT222']

def type(file):
    for value in file.column1:
        if value in numbers:
            print(value)

for file in files:
    type(file)

1 голос
/ 29 мая 2020

Попробуйте это

for file in glob.glob('data*.csv'):       # loop through each file
    df = pd.read_csv(file,                # create the DataFrame of the file
             encoding='ISO-8859-1', 
             error_bad_lines=False)
    result = df.where( \                  # Check where the DF contains these numbers
                 df.isin(numbers)) \
                .melt()['value'] \        # melt the DF to be a series of 'value'
                .dropna() \               # Remove any nans (non match)
                .unique().tolist()        # Return the unique values as a list.
    if result:                            # If there are any results 
        print(file, ', '.join(result)     # print the file name, and the results

Удалите комментарии и конечные пробелы, если вы копируете и вставляете код. для строки result, если вы столкнетесь с SyntaxError.

Как уже упоминалось, вы сможете сделать то же самое и без DataFrame:

for file in glob.glob('data*.csv'):
    data = file.read()
    for num in numbers:
        if num in data:
            print(file, num)
0 голосов
/ 29 мая 2020

Я бы посоветовал изменить функцию типа и назвать ее немного иначе

    def type(x):
        for i in x.column1:
            if i == numbers[0]:
                print(i, numbers[0])
            elif i == numbers[1]:
                print(i, numbers[1])
            elif i == numbers[2]:
                print(i, numbers[2])
            elif i == numbers[3]:
                print(i, numbers[3])
            elif i == numbers[4]:
                print(i, numbers[4])

    for j in filenames:
            type(j)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...