Как печатать значения с похожей строкой?

#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 , добавление некоторых цепочек -> карты отелей и использование вместо этого более богатых данных.