#python #python-3.x
#python #python-3.x
Вопрос:
Моя цель — прочитать большой csv-файл и распечатать все похожие значения, поскольку все это касается отелей, и для упрощения я составлю список dicts здесь для этого кода:
S1 = [{'name': 'Holiday Inn A','price': '552'},
{'name': 'Holiday Inn B','price': '568'},
{'name': 'Holiday Inn C','price': '589'},
{'name': 'Grand Palace','price': '768'}
and so on...]
Я имею в виду, что я хочу распечатать все значения с именем ‘Holiday Inn’ в нем, это мой желаемый результат:
Holiday Inn A
Holiday Inn B
Holiday Inn C
Вот мой код:
import csv
name = []
value = []
linked = []
a = []
def filereader():
line_count = 0
with open('hotelRev.csv','r', encoding ='utf-8') as fileIn:
reader = csv.reader(fileIn)
for row in reader:
line_count = line_count 1
if line_count == 1:
name.append(row)
else:
value.append(row)
for x in name:
for y in value:
linked.append(dict(zip(x,y)))
filereader()
for row in linked:
a.append(row['name'])
b = sorted(set(a))
for row in linked:
print(row['name']['Holiday Inn'])
и, очевидно, это не работает, так что у кого-нибудь есть представление о том, как это сделать?
редактировать-1: под подобным я подразумеваю классификацию всех элементов Holiday Inn в большую группу, чтобы их было легче вызывать и печатать.
Прямой пример из самого набора данных:
Holiday Inn Express amp; Suites Austin South
Holiday Inn Express amp; Suites Baton Rouge East
Holiday Inn Express amp; Suites Bethlehem
Holiday Inn Express amp; Suites Bloomington
Holiday Inn Express amp; Suites Butte
Holiday Inn Express amp; Suites Carmel-north Indianapolis
Holiday Inn Express amp; Suites Carpinteria
Holiday Inn Express amp; Suites Columbus - Polaris Parkway
Holiday Inn Express amp; Suites Columbus Univ Area - Osu
Holiday Inn Express amp; Suites Denver Northeast - Brighton
если возможно, я хотел бы найти способ распечатать их с как можно меньшим количеством строк
Ответ №1:
Это базовое решение с использованием наборов. Я думаю, что это будет неэффективно для очень большого набора данных, но на него можно ссылаться для создания эффективного решения.
import pandas as pd
import re
df = pd.read_csv('HotelNames.csv')
search_terms = input('Enter search terms: ')
#Convert to lower case
search_terms = search_terms.lower()
#Remove special characters except space
search_terms = re.sub(r"[^a-zA-Z0-9] ", ' ', search_terms)
#Make a list of words from the string
temp = search_terms.split(' ')
search_set = set()
for i in range(len(temp)):
#Make a set of unique words
search_set.add(temp[i])
for i in range(len(df)):
t = re.sub(r"[^a-zA-Z0-9] ", ' ', df.iloc[i][0])
t = t.lower()
temp = t.split(' ')
hotel_set = set()
for j in range(len(temp)):
hotel_set.add(temp[j])
#Find whether the searched terms are a subset of the hotel name in that particular row
if(search_set.issubset(hotel_set)):
print(df.iloc[i][0])
В HotelNames.csv
настоящее время содержит 1 столбец, то есть названия отелей.
Комментарии:
1. Спасибо за помощь! Но, к сожалению, я все еще любитель кодирования, поэтому я не знаю, как много в написанном вами коде, может быть, вы сможете немного объяснить это?
2. что я хочу знать, это модуль panda, модуль re? штуковина .sub и штуковина iloc
3. Вам придется искать в Google и учиться на практике. Модуль Pandas используется для чтения файлов данных (например, csv) в фреймы данных (табличная структура). Один из способов доступа к строке в фрейме данных — использовать ‘iloc’. Модуль RE предназначен для регулярных выражений, из которых я использовал ‘sub’ для удаления специальных символов (amp;, -), чтобы не нужно было вводить его в поиске. Вы можете поместить операторы печати везде, чтобы облегчить понимание.
4. Спасибо! Я обязательно попробую код, когда буду свободен! и да, я буду гуглить столько, сколько смогу, мой учитель все еще учит меня этим базовым операторам, и это отстой
Ответ №2:
Я думаю, что не хватает четкого определения того, что вы подразумеваете под подобным. Я рекомендую вам использовать функцию или метод, который возвращает логическое значение true, если две строки соответствуют вашему определению similar . Как только вы это разработаете, остальное должно встать на свои места с помощью оператора if.
Несколько тестовых строк для рассмотрения.. (вы сами решаете, похожи ли они и почему)
«Holiday inn » «Holiday inn » «holiday inn» «holiday_inn» «holiday inn» «lollyday inn» «^ * $% __holiday inn!» «The San Francisco Holiday Inn and Suites» и т. Д.
Одна вещь, на которую вы, возможно, захотите взглянуть и ознакомиться, — это концепция фонетического расстояния. Вот библиотека Python для этого .. https://github.com/jamesturk/jellyfish
Комментарии:
1. CSV-файл, который у меня есть, представлен в формате, в котором названия отелей имеют интервал между ними, прямой пример этого здесь, из самого файла данных:
Holiday Inn Express amp; Suites Austin South Holiday Inn Express amp; Suites Baton Rouge East Holiday Inn Express amp; Suites Bethlehem Holiday Inn Express amp; Suites Bloomington
я хочу классифицировать их все в один большой список, чтобы было проще распечатать их все, если я пометил Holiday Inn
Ответ №3:
Судя по вашим комментариям, похоже, что ваши данные на самом деле довольно структурированы (хотя для очистки некоторых записей может потребоваться небольшое редактирование). Один из подходов, который вы могли бы предпринять, — это посмотреть на группы имен с общими префиксами.
Я буду использовать слова вместо символов и вспомогательные функции dict вместо класса, чтобы сделать это как можно более простым.
ITEMS_KEY = None # Anything that isn't a string is safe here
def add_item(lookup, item):
words = item.split()
# e.g.: ["Holiday", "Inn", "Express", "amp;", "Suites", "Austin", "South"]
for word in words:
# Add a lower level lookup if needed
lookup = lookup.setdefault(word, {})
# Making this word.lower() makes searches case-insensitive
lookup.setdefault(ITEMS_KEY, set()).add(item) # Add the full item
# e.g.:
# lookup = {"Holiday": {"Inn": {"Express": ... {"South: {None: set(["Holiday Inn Express ..."]}}
def get_items_matching_prefix(lookup, prefix):
# Simple version with full words only
# Find the tree of results
words = prefix.split()
for word in words:
lookup = lookup.get(word, {})
return all_values(lookup)
def all_values(lookup):
# Collect all the results
ret = set()
for k, v in lookup.iteritems():
if k == ITEMS_KEY:
ret.update(v)
else:
ret.update(all_values(v))
return ret
csv_data = [
"Holiday Inn Express amp; Suites Austin South",
"Holiday Inn Express amp; Suites Austin North",
"Holiday Inn Oriental Express",
]
lookup = {} # Could be a class or recursive collections.defaultdict
for row in csv_data:
# e.g. row = "Holiday Inn Express amp; Suites Austin South"
add_item(lookup, row)
print get_items_matching_prefix(lookup, "Holiday Inn")
# set(['Holiday Inn Oriental Express', 'Holiday Inn Express amp; Suites Austin North', 'Holiday Inn Express amp; Suites Austin South'])
print get_items_matching_prefix(lookup, "Holiday Inn Express")
# set(['Holiday Inn Express amp; Suites Austin North', 'Holiday Inn Express amp; Suites Austin South'])
Более продвинутым методом может быть попытка поиска набора общих подстрок, определение того, что это отели, и анализ вашего csv в метаданные Hotel , добавление некоторых цепочек -> карты отелей и использование вместо этого более богатых данных.