【问题标题】:Need a list of row-values in pandas需要熊猫中的行值列表
【发布时间】:2021-02-23 15:01:20
【问题描述】:

我有什么,我需要什么

我有一个 pandas DataFrame p 和 cols 'a''b''c'(col 名称存储在 pc)。

据此,我想创建一个形状相同的 DataFrame pn,但每个单元格都是来自选定行的 值列表。 DataFrame n 告诉我从p 中为pn 中的每一行选择哪些行。

import pandas as pd

pc = ['a', 'b', 'c']
p  = pd.DataFrame([[11, 12, 13],
                   [21, 22, 23]],
                  columns=pc,
                  index=[1001,
                         1002])

n  = pd.DataFrame([[[1001]      ],
                   [[1001, 1002]]],
                  columns=['sel_row'],
                  index=[1001,
                         1002])

可以(以及想要)实现的目标

我能得到的最远...给我一个列列表,而不是行。 那么,我是否混淆了嵌套的 for 循环?

pn = pd.DataFrame([ [p.loc[ix, pc].values for ix in n.loc[indx].values[0]] 
                    for indx in n.index ])

print (pn)

# The actual output:
#               0             1
# 0  [11, 12, 13]          None
# 1  [11, 12, 13]  [21, 22, 23]

# The required output:
#           0         1         2
# 0  [11]      [12]      [13]
# 1  [11, 21]  [12, 22]  [13, 23]

杂念

也许我也应该迭代类似p.loc[ix, c] ... for c in pc...但怎么会有3个循环??

另一个(可选的)愿望

lambda 也可以吗?我的直觉是:那会更快——但不确定!

感谢您解决问题或提供任何帮助。

【问题讨论】:

    标签: python pandas list dataframe


    【解决方案1】:

    你可以分解n,用它来分割p和groupby:

    s = n['sel_row'].explode()
    p.loc[s].groupby(s.index).agg(list)
    

    输出:

                 a         b         c
    1001      [11]      [12]      [13]
    1002  [11, 21]  [12, 22]  [13, 23]
    

    【讨论】:

      【解决方案2】:

      您可以在此处编写自定义函数。

      pc = ['a', 'b', 'c']
      p  = pd.DataFrame([[11, 12, 13],
                         [21, 22, 23]],
                        columns=pc,
                        index=[1001,
                               1002])
      
      n  = pd.DataFrame([[[1001]      ],
                         [[1001, 1002]]],
                        columns=['sel_row'],
                        index=[1001,
                               1002])
      def f(idx):
          return pd.Series(p.loc[idx, :].values.T.tolist())
      
      n.sel_row.apply(f)
      
                   0         1         2
      1001      [11]      [12]      [13]
      1002  [11, 21]  [12, 22]  [13, 23]
      

      使用lambda 可以将上面重写为:

      n.sel_row.apply(lambda idx: pd.Series(p.loc[idx, :].values.T.tolist()))
      

      【讨论】:

      • 我最喜欢这个答案......因为它看起来非常简单易懂。只是困惑地看到 f 在没有其参数 idx 的情况下如何应用!
      • 我想我明白了:idxn.sel_row 的每个元素!我实际上对语法更熟悉:n.sel_row.apply(lambda idx: f(idx))。感谢这个快捷方式! ?
      【解决方案3】:

      IIUC,你可以这样做:

      data = [[[*x] for x in zip(*p.loc[idxs].values)] for idxs in n['sel_row']]
      
      result = pd.DataFrame(data=data, columns=p.columns, index=p.index)
      print(result)
      

      输出

                   a         b         c
      1001      [11]      [12]      [13]
      1002  [11, 21]  [12, 22]  [13, 23]
      

      【讨论】:

      • 谢谢。是的,那些列名和索引非常有用!
      猜你喜欢
      • 2017-07-21
      • 2022-10-15
      • 2022-11-24
      • 2022-12-23
      • 1970-01-01
      • 2016-05-28
      • 2022-11-12
      • 2021-05-19
      • 1970-01-01
      相关资源
      最近更新 更多