Совпадение нескольких элементов в нескольких файлах CSV - PullRequest
0 голосов
/ 06 июля 2018

У меня есть два файла CSV, каждый из которых содержит столбцы для даты и времени. Для КАЖДОЙ строки мне нужно сопоставить время и дату в CSV 1 и CSV 2 и извлечь Weather из CSV 2.

CSV 1:

    Date           Time    Value
    2017/04/20     12:00   100
    2017/03/20     12:00   250
    2017/03/20     12:00   300
    2017/02/20     12:00   80
    2017/02/20     12:00   500

CSV 2:

    Date           Time    Weather
    2017/02/20     12:00   Sunny
    2017/02/20     12:00   Sunny
    2017/03/20     12:00   Sunny
    2017/03/20     12:00   Sunny
    2017/04/20     12:00   Sunny

Я не знаю, насколько это эффективно, но первым делом я добавил файлы CSV в два списка Python:

list1 = []
list2 = []
for row in CSV1:
    list1.append(row)
for row in CSV2:
    list2.append(row)

Затем я выбираю дату и тип для каждой строки в списке list1 и сразу перебираю каждую строку в списке list2 до совпадения элементов.

for row in list1:
    published_date = row[0]
    published_time = row[1]
    for rows in list2:
        if published_date == rows[0] and published_time == rows[1]:
            "do something with rows[2]"
            break

Это работает, но CSV1 имеет 1700 строк, а CSV2 имеет 1 000 000 строк, поэтому этот процесс занимает 150 секунд. Есть ли значительно более быстрый способ?

Я знаю, что есть решения, в которых один элемент должен соответствовать, но здесь их 2, и я не смог настроить одноэлементные решения для работы.

Я новичок в Stack Overflow, поэтому, если я что-то не так сделал в этом сообщении, пожалуйста, сообщите мне.

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

Я бы порекомендовал вам проверить библиотеку "pandas" в Python. Это может помочь вам с вопросом эффективности. Мне было любопытно, и я реализовал проблему в Pandas, и мне удалось завершить задачу, используя несколько фиктивных данных за 373 миллисекунды.

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

# Generating some random samples
import pandas as pd
date_range = pd.date_range(start='2017-04-20',periods=1700)
time_range = pd.to_datetime(pd.date_range('12:00', freq='1H', periods=1700).strftime('%H:%m'))
values = np.arange(0,1700)
weather = np.random.choice(['rain','sunny','windy'],size=1700, replace=True)

# Putting the Random Data into a DataFrame
df1 = pd.DataFrame({'Date':date_range,
                    'Time':time_range,
                   'Value':values})

df2 = pd.DataFrame({'Date':np.random.choice(date_range, size=1000000, replace=True),
                    'Time': np.random.choice(time_range, size=1000000, replace=True),
                   'Weather':np.random.choice(weather, size=1000000, replace=True)})

# Mergind the Datatogther on the Date and Time Columns
df3 = pd.merge(df1,df2,on=['Date','Time'], how='inner')
df3
0 голосов
/ 06 июля 2018

Вам нужно проверить, что кортеж (row[0], row[1]) уже виден в другом файле.

Наиболее естественной структурой данных для этого является set.

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

dates_times = {(items[0], items[1]) for items in (line.split() for lines in CSV1)}
for line in CSV2:
    items = line.split()
    if (items[0], items[1]) in dates_times:
        do_someting_with(items[2]
0 голосов
/ 06 июля 2018

Список неэффективен при поиске членства. Вместо этого используйте dict, так как вам нужно также привязать дату и время к погоде. Вы можете прочитать CSV2 в диктовку, проиндексированную кортежем даты и времени:

weather_history = {tuple(row[:2]): row[2] for row in CSV2}

Так что это будет диктат вроде:

{('2017/02/20', '12:00'): 'Sunny',  ('2017/02/20', '12:00'): 'Sunny', ... }

Чтобы вы могли выполнять поиск гораздо эффективнее:

for row in list1:
    published_date, published_time = row[:2]
    if (published_date, published_time) in weather_history:
        # do something with weather_history[(published_date, published_time)], which is the weather of that date and time
...