【问题标题】:convert list to dataframe using dictionary使用字典将列表转换为数据框
【发布时间】:2019-07-24 03:52:19
【问题描述】:

我是 Pythonland 的新手,我有一个问题。我有一个如下列表,想将其转换为数据框。

我在 Stackoverflow 上读到,创建字典比创建列表更好,所以我创建一个如下。

column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries

row_names = ["jack", "mick", "nick","pick"]

data = ['100','50','A','107','62','B'] # The actual list has 1640 entries

dic = {key:[] for key in column_names}
dic['name'] = row_names
t = 0
while t< len(data):
    dic['height'].append(data[t])
    t = t+3
t = 1
while t< len(data):
    dic['weight'].append(data[t])
    t = t+3

以此类推,我有 10 列,所以我将上面的代码写了 10 次以完成完整的字典。然后我转换 它到数据框。它工作得很好,必须有 以更短的方式做到这一点。我不知道如何用数字引用字典的键。它是否应该被包装到一个函数中。另外,如何在执行下一个循环之前自动将 t 的值加一?请帮帮我。

【问题讨论】:

  • 您在示例行/列名称中缺少几个引号。另外,我想我了解断开连接,看看您的数据是如何创建的。问题最有可能建议创建 dict 的方式是,数据位于 的逻辑组中,这通常是我们应该如何看待数据帧。

标签: python loops dataframe dictionary iterator


【解决方案1】:

您可以像这样遍历columnn_names

dic = {key:[] for key in column_names}
dic['name'] = row_names
for t, column_name in enumerate(column_names):
    i = t
    while i< len(data):
        dic[column_name].append(data[i])
        i += 3

Enumerate 会自动遍历 t 从 0 到 len(column_names)-1

【讨论】:

  • 感谢您的快速响应,但上面的代码也会枚举键 'name',因此无法实现所需的输出。
  • 所以你可以从你将要迭代的列表中排除它。 for t, column_name in enumerate(column_names[1:]):
【解决方案2】:
i = 0
while True:
    try:
        for j in column_names:
            d[j].append(data[i])
            i += 1

    except Exception as er:  #So when i value exceed by data list it comes to exception and it will break the loop as well
        print(er, "################")
        break

【讨论】:

    【解决方案3】:

    您将所有列数据连接到一个列表的第一个问题。您应该首先研究如何防止它,并将每个列值的列表列表放在一个单独的列表中,例如[['100', '107'], ['50', '62'], ['A', 'B']]。您需要此数据结构以高效进行的任何方式:

    cl_count = len(column_names)
    d_count = len(data)
    spl_data = [[data[j] for j in range(i, d_count, cl_count)] for i in range(cl_count)] 
    

    那么你应该使用dict理解。 这是 Python 3.x 的一项功能,因此它在 Py 2.x 中不起作用。

    df = pd.DataFrame({j: spl_data[i] for i, j in enumerate(column_names)})
    

    【讨论】:

      【解决方案4】:

      首先,我们应该了解数据框的理想字典应该是什么样子。

      可以通过两种不同的方式来考虑 Dataframe:
      一种是传统的行集合..

      'row 0':  ['jack', 100, 50, 'A'],
      'row 1':  ['mick', 107, 62, 'B']
      

      不过,还有另一种更有用的表示,虽然一开始可能不那么直观。
      列集合:

      'name': ['jack', 'mick'],
      'height': ['100', '107'],
      'weight': ['50', '62'],
      'grade': ['A', 'B']
      

      现在,这是要实现的关键,第二个表示更有用 因为这是数据帧中相互支持和使用的表示。
      它不会在单个分组中遇到数据类型冲突(每列需要有 1 个固定数据类型) 但是,在行表示中,数据类型可能会有所不同。
      此外,可以在整个色谱柱上轻松一致地执行操作 因为这种连贯性是无法保证的。

      因此,tl;dr DataFrame 本质上是等长列的集合。

      因此,该表示形式的字典可以轻松转换为 DataFrame。

      column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries
      
      row_names = ["jack", "mick"]
      
      data = [100, 50,'A', 107, 62,'B'] # The actual list has 1640 entries
      

      因此,考虑到这一点,首先要意识到的是,在其当前格式中,data 是一种非常糟糕的表示形式。 它是合并到单个列表中的行的集合。

      如果您是控制数据形成方式的人,那么要做的第一件事就是不要以这种方式准备数据。

      目标是每列的列表,理想情况下,以该格式准备列表。

      但是,现在,如果以这种格式给出,您需要相应地迭代和收集值。这是一种方法

      column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries
      row_names = ["jack", "mick"]
      data = [100, 50,'A', 107, 62,'B'] # The actual list has 1640 entries
      
      dic = {key:[] for key in column_names}
      dic['name'] = row_names
      print(dic)
      

      目前的输出:

      {'height': [],
       'weight': [],
       'grade': [],
       'name': ['jack', 'mick']} #so, now, names are a column representation with all correct values.
      
      remaining_cols = column_names[1:]
      
      #Explanations for the following part given at the end
      data_it = iter(data)
      for row in zip(*([data_it] * len(remaining_cols))):
          for i, val in enumerate(row):
              dic[remaining_cols[i]].append(val)
      
      print(dic)
      

      输出:

      {'name': ['jack', 'mick'],
       'height': [100, 107],
       'weight': [50, 62],
       'grade': ['A', 'B']}
      

      我们已经完成了表示

      最后:

      import pd
      df = pd.DataFrame(dic, columns = column_names)
      print(df)
         name  height  weight grade
      0  jack     100      50     A
      1  mick     107      62     B
      

      编辑: zip部分的一些解释: zip 接受任何可迭代对象,并允许我们一起迭代它们。

      data_it = iter(data) #prepares an iterator. 
      
      [data_it] * len(remaining_cols) #creates references to the same iterator
      

      这里,这类似于[data_it, data_it, data_it]

      *[data_it, data_it, data_it] 中的 * 允许我们将列表解压缩为 zip 函数的 3 个参数 因此,对于任何函数 f,f(*[data_it, data_it, data_it]) 等价于 f(data_it, data_it, data_it)

      这里的神奇之处在于,遍历迭代器/推进迭代器现在将反映所有引用的变化

      把它们放在一起: zip(*([data_it] * len(remaining_cols))) 实际上允许我们一次从数据中获取 3 项,并将其分配给行 所以,row = (100, 50, 'A') 在 zip 的第一次迭代中

      for i, val in enumerate(row): #just iterate through the row, keeping index too using enumerate
          dic[remaining_cols[i]].append(val) #use indexes to access the correct list in the dictionary
      

      希望对您有所帮助。

      【讨论】:

        【解决方案5】:

        如果您使用 Python 3.x,正如 l159 所建议的那样,您可以使用理解 dict,然后从中创建一个 Pandas DataFrame,使用名称作为行索引:

        data = ['100', '50', 'A', '107', '62', 'B', '103', '64', 'C', '105', '78', 'D']
        column_names = ["height", "weight", "grade"]
        row_names = ["jack", "mick", "nick", "pick"]
        
        df = pd.DataFrame.from_dict(
            {
                row_label: {
                    column_label: data[i * len(column_names) + j]
                    for j, column_label in enumerate(column_names)
                } for i, row_label in enumerate(row_names)
            },
            orient='index'
        )
        

        实际上,中间字典是一个嵌套字典:外部字典的键是行标签(在这种情况下是row_names 列表的项);与每个键关联的值是一个字典,其键是列标签(即column_names 中的项目),值是data 列表中的对应元素。

        函数from_dict用于创建DataFrame实例。

        所以,前面的代码产生以下结果:

             height weight grade
        jack    100     50     A
        mick    107     62     B
        nick    103     64     C
        pick    105     78     D
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-06-12
          • 2021-05-21
          • 1970-01-01
          • 1970-01-01
          • 2019-04-21
          • 1970-01-01
          • 2019-04-28
          相关资源
          最近更新 更多