【问题标题】:python pandas dataframe to dictionarypython pandas数据框到字典
【发布时间】:2013-09-12 18:53:13
【问题描述】:

我有一个两列数据框,并打算将其转换为 python 字典 - 第一列将是键,第二列将是值。先感谢您。

数据框:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4

【问题讨论】:

标签: python dictionary pandas


【解决方案1】:

如果你设置索引比字典会产生唯一的键值对

encoder=LabelEncoder()
df['airline_enc']=encoder.fit_transform(df['airline'])
dictAirline= df[['airline_enc','airline']].set_index('airline_enc').to_dict()

【讨论】:

    【解决方案2】:

    我在尝试使用 pandas 数据框的 列制作字典时发现了这个问题。在我的情况下,数据框有 A、B 和 C 列(假设 A 和 B 是经度和纬度的地理坐标,C 是国家/地区/州/等,或多或少是这种情况)。

    我想要一个字典,其中每对 A、B 值(字典键)与相应行中的 C 值(字典值)匹配(保证 A、B 值的每个 pair由于之前的过滤而唯一,但在这种情况下,对于不同的 A、B 值对,C 的值可能相同),所以我这样做了:

    mydict = dict(zip(zip(df['A'],df['B']), df['C']))
    

    使用 pandas to_dict() 也可以:

    mydict = df.set_index(['A','B']).to_dict(orient='dict')['C']
    

    (在执行创建字典的行之前,A 或 B 列均未用作索引)

    这两种方法都很快(在 85k 行的数据帧上,使用 5 年的快速双核笔记本电脑上不到一秒)。

    我发这个的原因:

    1. 对于那些需要这种解决方案的人
    2. 如果有人知道执行速度更快的解决方案(例如,对于数百万行),我将不胜感激。

    【讨论】:

      【解决方案3】:

      这是我的解决方案:

      import pandas as pd
      df = pd.read_excel('dic.xlsx')
      df_T = df.set_index('id').T
      dic = df_T.to_dict('records')
      print(dic)
      

      【讨论】:

        【解决方案4】:
        def get_dict_from_pd(df, key_col, row_col):
            result = dict()
            for i in set(df[key_col].values):
                is_i = df[key_col] == i
                result[i] = list(df[is_i][row_col].values)
            return result
        

        这是我的 sloution,一个基本循环

        【讨论】:

          【解决方案5】:

          最简单的解决方案:

          df.set_index('id').T.to_dict('records')
          

          例子:

          df= pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id','value'])
          df.set_index('id').T.to_dict('records')
          

          如果您有多个值,例如 val1、val2、val3 等,并且您希望它们作为列表,请使用以下代码:

          df.set_index('id').T.to_dict('list')
          

          【讨论】:

          【解决方案6】:

          你可以使用'dict理解'

          my_dict = {row[0]: row[1] for row in df.values}
          

          【讨论】:

          • 在内存使用方面,使用 pandas 循环并不是最有效的。见:engineering.upside.com/…
          • OP 没有要求最有效的答案,所以我认为@Dongwan Kim 提供了不错的替代解决方案。
          【解决方案7】:

          您需要一个列表作为字典值。这段代码可以解决问题。

          from collections import defaultdict
          mydict = defaultdict(list)
          for k, v in zip(df.id.values,df.value.values):
              mydict[k].append(v)
          

          【讨论】:

            【解决方案8】:

            在某些版本中,下面的代码可能不起作用

            mydict = dict(zip(df.id, df.value))
            

            所以说清楚

            id_=df.id.values
            value=df.value.values
            mydict=dict(zip(id_,value))
            

            注意我用id_是因为id是保留字

            【讨论】:

            • 同意,它对我不起作用。但是df.id怎么办呢,列名id是不被识别为数据框变量的吧?如,写入数据框对象库的变量。我一定是误会了什么。
            【解决方案9】:

            另一个(略短)不丢失重复条目的解决方案:

            >>> ptest = pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id','value'])
            >>> ptest
              id  value
            0  a      1
            1  a      2
            2  b      3
            
            >>> pdict = dict()
            >>> for i in ptest['id'].unique().tolist():
            ...     ptest_slice = ptest[ptest['id'] == i]
            ...     pdict[i] = ptest_slice['value'].tolist()
            ...
            
            >>> pdict
            {'b': [3], 'a': [1, 2]}
            

            【讨论】:

              【解决方案10】:
              mydict = dict(zip(df.id, df.value))
              

              【讨论】:

              • 注意:如果索引是所需的字典键,则执行:dict(zip(df.index,df.value))
              【解决方案11】:

              请参阅to_dict 的文档。你可以这样使用它:

              df.set_index('id').to_dict()
              

              如果你只有一列,避免列名也是dict中的一个级别(实际上,在这种情况下你使用Series.to_dict()):

              df.set_index('id')['value'].to_dict()
              

              【讨论】:

              • 请注意,如果ID列中存在冗余值,此命令将丢失数据:>>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) >>> ptest.set_index('id')['value'].to_dict()
              • 我不得不说,该文档链接中没有任何内容可以为我提供这个问题的答案。
              • @bombayquant 请参阅下面的 DSM 和我的答案。请注意,这是一个 4 年前的讨论。
              【解决方案12】:

              如果您想要一种简单的方法来保留重复项,您可以使用groupby

              >>> ptest = pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) 
              >>> ptest
                id  value
              0  a      1
              1  a      2
              2  b      3
              >>> {k: g["value"].tolist() for k,g in ptest.groupby("id")}
              {'a': [1, 2], 'b': [3]}
              

              【讨论】:

              • 漂亮而优雅的解决方案,但是在 50k 行的表上,它比我下面的丑陋解决方案慢了大约 6 倍。
              • @dallologm:你能举一个例子表吗?如果它比 Python 循环慢六倍,那么 pandas 中可能存在性能错误。
              【解决方案13】:

              joris 在这个线程中的答案和punchagan 在duplicated thread 中的答案非常优雅,但是如果用于键的列包含任何重复值,它们将不会给出正确的结果。

              例如:

              >>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) 
              >>> ptest
                id  value
              0  a      1
              1  a      2
              2  b      3
              
              # note that in both cases the association a->1 is lost:
              >>> ptest.set_index('id')['value'].to_dict()
              {'a': 2, 'b': 3}
              >>> dict(zip(ptest.id, ptest.value))
              {'a': 2, 'b': 3}
              

              如果您有重复的条目并且不想丢失它们,您可以使用这个丑陋但有效的代码:

              >>> mydict = {}
              >>> for x in range(len(ptest)):
              ...     currentid = ptest.iloc[x,0]
              ...     currentvalue = ptest.iloc[x,1]
              ...     mydict.setdefault(currentid, [])
              ...     mydict[currentid].append(currentvalue)
              >>> mydict
              {'a': [1, 2], 'b': [3]}
              

              【讨论】:

              • 由于cmets中缺少块,请原谅格式化:mydict = defaultdict(list)\n for (key, val) in ptest[["id", "value"]].itertuples(index=False):\n mydict[key].append(val)
              • 虽然不像单线那么优雅,但我更喜欢你的解决方案。
              猜你喜欢
              • 2016-04-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-05-02
              • 2023-03-13
              • 2017-10-15
              相关资源
              最近更新 更多