【问题标题】:Pulling data from csv file for specific columns that user inputs (no pandas)从用户输入的特定列的 csv 文件中提取数据(无熊猫)
【发布时间】:2020-06-08 11:46:11
【问题描述】:

我需要有关代码的帮助,该代码从我拥有的大型 csv 文件中获取用户想要的特定列的输入。在他们自己输入他们想要的列之后,他们还必须输入一个整数输入。该整数输入将为他们提供该列的最低出现次数的结果。例如,如果他们输入:hospital_name, "5",它将向他们显示 5 个不同的医院(该列下至少有 50 个不同的医院名称),它们的数量最少。我会写一个输入输出的例子:

在您想要的列中输入:医院名称 输入您想要的最低结果数:3

输出可能如下所示:

                      400 births are tied to Gains Hospital                                                                            
                      347 births are tied to Petri Hospital 
                      200 births are tied to Brit Hospital 

整个 csv 是关于出生的报告,因此您必须计算每个项目在每列中出现的次数并报告(最低计数)

我已经使用“with”读取了我的 csv 文件

我无法通过循环来连接所有这些。 我知道用户输入本身将是 input() 和 int(input()),但这并没有将我连接回 csv 文件。

【问题讨论】:

  • 软件如何知道您想将出生显示为医院名称。这意味着您输入 column_name 作为医院。它如何知道您希望查看不同医院的分娩情况,而不是 CSV 文件中的其他列?
  • 整个 csv 是关于出生的报告,所以你必须使用 COUNT 我很确定。你必须计算一个项目在每一列中出现的次数,这有意义吗?
  • @webbpie--一行是否显示医院的所有分娩,或者医院的分娩是否可以多行显示,这需要医院的总和?意思是一行是400,Gains 或者您是否多次提到了 Gains 医院,您必须添加带有 Gains 的行才能达到 400?
  • 好问题,我应该澄清一下,对不起!这是您说的最后一件事,因此您将计算 Gains 在该列中出现的次数并报告该数字。如果用户想要 3 个结果,它应该为他们指定的列中的项目输出 3 个最低计数。
  • @webbpie--好的,看看我刚刚发布的答案。

标签: python csv file for-loop user-input


【解决方案1】:

代码

import csv

column_name = input('Which column: ').upper()
number_lowest = int(input('How many lowest: '))

# Calculate births by specified column name
with open("data.csv", "r") as f:
  reader = csv.DictReader(f, skipinitialspace=True, delimiter=",")
  births_count = {}
  for d in reader:
    # Use column_name as key
    # accumulate births for this key
    if not d[column_name] in births_count:
      births_count[d[column_name]] = 0
    births_count[d[column_name]] += 1 # since each row is a different birth

# Find number_lowest lowest births
lowest_births = {}
for i in range(number_lowest):
  # By looping number_lowest times, 
  # we find this many lowest values
  if len(births_count) > 0:
    # find lowest births
    lowest_val = 1e37 # just use a large number
                      # that we know actual
                      # count will be less than

    lowest_name = ""
    for name, value in births_count.items():
      if value < lowest_val:
        lowest_val = value
        lowest_name = name

    # Add to lowest births
    lowest_births[lowest_name] = lowest_val

    # remove from births_count
    # this reduces count of items in dictionary
    del births_count[lowest_name]
  else:
    break  # births_count is empty

# Output results
for name, births in lowest_births.items():
  print(f"{births} births are tied to {name} {column_name.title()}")

测试

由逗号分隔的 CSV 数据组成,包含三列:出生、医院、位置

File: data.csv

HOSPITAL_NAME,BIRTH_DAY, BIRTH_YEAR, BIRTH_WEIGHT
Gains,1/14,2015,8.5 lbs
Mayo Clinic,2/11,2018,6.5 lbs
Gains,1/15,2016,8.9 lbs
Stanford Health Care,2/15,2016,7.4 lbs
Mayo Clinic,11/10,2018,7.3 lbs
Gains,1/09,2011,7.5 lbs
John Hopkins,12/23,2012,6.9 lbs
Massachusetts General,9/14,2001,8.3 lbs
Stanford Health Care,8/17,2005,7.6 lbs
Massachusetts General,7/18,2016,8.7 lbs
John Hopkins,3/11,2017,7.2 lbs
Massachusetts General,4/16,2014,7.4 lbs
Northwestern Memorial,10/12,2012,8.3 lbs
UCLA Medical Center,9/19,2011,8.1 lbs
Petri,11/21,2003,7.5 lbs
UCSF Medical Center,2/15,2004,7.9 lbs

示例运行:

Which column: hospital_name
How many lowest: 5
HOSPITAL_NAME
1 births are tied to Northwestern Memorial Hospital_Name
1 births are tied to UCLA Medical Center Hospital_Name
1 births are tied to Petri Hospital_Name
1 births are tied to UCSF Medical Center Hospital_Name
2 births are tied to Mayo Clinic Hospital_Name

使用插入排序更新 Find Max

import csv

# Source: https://www.geeksforgeeks.org/python-program-for-insertion-sort/
def insertionSort(arr): 
  " Inplace location sort "
  # Traverse through 1 to len(arr) 
  for i in range(1, len(arr)): 
    key = arr[i] 
    # Move elements of arr[0..i-1], that are 
    # greater than key, to one position ahead 
    # of their current position 
    j = i-1
    while j >=0 and key < arr[j] : 
            arr[j+1] = arr[j] 
            j -= 1
    arr[j+1] = key

def find_maxs_by_sort(data, number):
  """ Finds extreems of mins or max's 
      depending upn bLowest flag
  """

  # Get list of key, value pairs as tuples of (value, key)
  tuple_list = []
  for k, v in data.items():
    tuple_list.append((v, k))

  # Sort will be in ascending order
  # Does an inplace sort
  # insertSort also works on array of tuples
  # Will sort by v since it's first in the each tuple
  insertionSort(tuple_list)

  # Place sorted tuples back as a dictionary
  # tuples are sorted by [(v1, k1), (v2, k2), ...]
  # We start at the end and work backwards since sort is
  # in ascending order
  n = len(tuple_list)
  results = {}
  for i in range(n-1, n - number - 1, -1):
    v, k = tuple_list[i]
    results[k] = v

  return results

for i in range(3):
  # To do this 3 times
  column_name = input('Which column: ').upper()
  number = int(input('How many maxs: '))

  with open("data.csv", "r") as f:
    reader = csv.DictReader(f, skipinitialspace=True, delimiter=",")
    births_count = {}
    for d in reader:
      # Use column_name as key
      # accumulate births for this key
      if not d[column_name] in births_count:
        births_count[d[column_name]] = 0
      births_count[d[column_name]] += 1 # since each row is a different birth

  # find max
  max_births = find_maxs_by_sort(births_count, number)

  # Output results
  for name, births in max_births.items():
    print(f"\t{births} births are tied to {name} {column_name.title()}")

【讨论】:

  • results[d[column_name]] += int(d['births']) ,这表明 'births' 是一个关键错误。
  • @webbpie——这里是online running code。您可以通过点击顶部的绿色运行按钮来运行它。
  • @webbpie -- 你是说这是一个没有标题行的 CSV 文件。只是为了确保:文件分隔符是什么?似乎需要三个输入:1)医院的列号,2)出生的列号,3)你想要多少最低行。这看起来正确吗?
  • 有 14 个不同的列标题。他们都有excel中的标题。例如,一个是 CITY_BIRTH。另外,如果没有 setdefault(),我将如何做到这一点?我们从来没有学过,所以我们不能使用它。对困惑感到抱歉。到目前为止,您的帮助非常好。
  • @webbpie--确定 setdefault 有 setdefault 的替代品。您能否提供数据的链接或部分数据的示例?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-18
  • 1970-01-01
  • 2020-10-30
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多