#python #pandas #numpy
Вопрос:
У меня есть набор данных, который выглядит так:
Мой вывод должен выглядеть так: Teams_and_seasons_output
В наборе данных перечислены очки за разные сезоны для 8 команд. Код должен отсортировать набор данных в порядке убывания по точкам, а затем объединить команды и очки и показать результаты в строке.
Я написал макрос vba в Excel, но когда количество строк достигло 250 тысяч, Excel набрал скорость улитки и занял 2 часа. Я хотел бы изменить эту обработку на Python, чтобы она работала быстрее. Однако я не являюсь экспертом в Python Numpy или Pandas, чтобы выполнять эту обработку, и я ищу помощи для достижения этой цели.
Спасибо за вашу помощь. Набор данных доступен в файле csv.
Ответ №1:
Я опубликую решение, но я не уверен, какое увеличение времени вы получите. Вам придется это проверить. Кроме того, я уверен, что есть более лаконичные решения, использующие pandas
или что-то в этом роде. Это решение только на python.
Основная стратегия состоит в том, чтобы просто сортировать каждую строку и отслеживать, какая команда связана с каким счетом.
Кроме того, если вы новичок в python, вы можете прочитать о понимании списков, если код не имеет смысла. Они представляют собой одну линию для петель. Пример:
a = [i for i in range(5)] #-gt; [0, 1, 2, 3, 4] b = [[i for i in range(3)] for j in range(2)] #-gt; [[0, 1, 2], [0, 1, 2]]
# parse the csv file - there is also a csv library you can look at def parseCSV(fname): # extract the rows from the file lines = None with open(fname) as f: lines = [line.strip().split(',') for line in f] # uncomment to view the data structure to ensure its consistent for line in lines: #print(line, sep=" ") continue # extract the teams and remove from lines teams = lines[0] lines = lines[1:] # not part of output, but if you need the seasons seasons = [line[0] for line in lines] # extract the data - parse it to integer scores = [[int(li) for li in line[1:]] for line in lines] # return the values return teams, seasons, scores def sortRow(row, teams): #associated each score with the team that scored it row = [(team_index, score) for team_index, score in enumerate(row)] # sort the row based on score (x[1]) - lambda x: x is an inline function # where x is the input (in this case (team_index, score) and x[1] tells # python to sort by the score value (since its at position 1) # the [::-1] at the end reverse the array since we want descending order sorted_row = sorted(row, key=lambda x: x[1])[::-1] # transform index and value to string format requested in output return [f'{teams[team_index]}-{score}' for team_index, score in sorted_row] # tie it all together formatted_data = [] teams, seasons, score_matrix = parseCSV('scores.csv') for row in score_matrix: formatted_row = sortRow(row, teams) formatted_data.append(formatted_row) # save to csv file all at once - to add to existing file replace 'w' with 'a' with open('sorted_scores.csv', 'w') as out: for row in formatted_data: out.write(f'{",".join(row).strip()}n')
И это был файл scores.csv
Team1, Team2, Team3, Team4, Team5, Team6, Team7, Team8 Season1, 22, 12, 12, 22, 14, 18, 28, 10 Season2, 14, 30, 16, 16, 18, 14, 16, 24 Season3, 24, 24, 16, 16, 28, 30, 16, 16 Season4, 20, 20, 14, 24, 12, 18, 20, 22 Season5, 30, 28, 10, 16, 24, 14, 14, 18
Комментарии:
1. Я проверю это. Код выглядит намного элегантнее, чем то, что у меня есть в Excel
2. привет @sin tribu, код сработал, как и ожидалось. Время выполнения было значительно меньше, чем у Excel VBA. Единственная проблема, с которой я сейчас сталкиваюсь, заключается в следующем: хочу ли я включить столбец комментариев в файл scores.csv. Как бы я это сделал? Я попробовал что-то вроде этого: final_data = список(zip(formatted_data, комментарии)); Я получил комментарии от parseCSV, как и другие столбцы. Проблема заключалась в том, что при записи в csv Python formatted_data жаловался, что «список не ожидался»
3. Рад, что это ускорило события, я не был уверен. Я не уверен, что понимаю, если нет, добавьте правку в свой вопрос, включая код, который у вас есть. Но я подозреваю, что если вы говорите
for row in final_data: out.write(row)
, что это ошибка, то это потому, что, когда выzip(formatted_rows, comments)
row
сейчас в форме[list, str]
. Распечатайте строку для проверки. Если это так, вы можете сказатьfor row, comment in final_data:
, что я позволю вам выяснить, как записать эти два в строки (ПОДСКАЗКА: out. запись принимает строку в качестве входных данных). Опубликуйте какой-нибудь код, если я неправильно понял. Ура!