在Pandas DataFrame中存储多维属性(列) - python

pandas DataFrame列中存储具有多个条目(固定长度)的项目的最佳方法是什么?我在想类似3D位置矢量的东西。例如,如果我的DataFrame正在存储有关一堆物理对象的数据,则可能看起来像这样:

df = pandas.DataFrame({
    'type': [1, 2, 1, 1, 3],
    'mass': [1.1, 2.2, 3.3, 4.4, 5.5],
    'pos': [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]],
    'vel': [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
})
#    mass           pos  type           vel
# 0   1.1     [1, 2, 3]     1     [1, 2, 3]
# 1   2.2     [4, 5, 6]     2     [4, 5, 6]
# 2   3.3     [7, 8, 9]     1     [7, 8, 9]
# 3   4.4  [10, 11, 12]     1  [10, 11, 12]
# 4   5.5  [13, 14, 15]     3  [13, 14, 15]

在这里,列'pos''vel'是3D空间中对象的位置和速度。

我想到了几种选择,但似乎都不理想,甚至都行不通:

  • 将Python列表存储为列中的值。这基本上就是我在上面的示例中显示的内容。不幸的是,这是非常低效的。
  • 将列拆分为几个不同的列:
    df = pandas.DataFrame({
        'type': [1, 2, 1, 1, 3],
        'mass': [1.1, 2.2, 3.3, 4.4, 5.5],
        'x': [1, 4, 7, 10, 13],
        'y': [2, 5, 8, 11, 14],
        'z': [3, 6, 8, 12, 15],
        'vx': [1, 4, 7, 10, 13],
        'vy': [2, 5, 8, 11, 14],
        'vz': [3, 6, 8, 12, 15]
    })
    #    mass  type  vx  vy  vz   x   y   z
    # 0   1.1     1   1   2   3   1   2   3
    # 1   2.2     2   4   5   6   4   5   6
    # 2   3.3     1   7   8   8   7   8   8
    # 3   4.4     1  10  11  12  10  11  12
    # 4   5.5     3  13  14  15  13  14  15
    

    对于较大的属性,这似乎变得很麻烦。但是至少有效吗?

  • 我也尝试为该列分配多维numpy数组,但不幸的是,pandas拒绝:
    pos = numpy.array([[11, 12, 13],
                       [22, 23, 24],
                       [33, 34, 35],
                       [44, 45, 46],
                       [55, 56, 57]])
    df.loc[:, 'pos'] = pos
    # ---------------------------------------------------------------------------
    # ValueError                                Traceback (most recent call last)
    # <ipython-input-228-2ee95dd5aa19> in <module>()
    # ----> 1 df.loc[:, 'pos'] = pos
    # 
    # /opt/anaconda-3/anaconda3/lib/python3.6/site-packages/pandas/core/indexing.py in __setitem__(self, key, value)
    #     177             key = com._apply_if_callable(key, self.obj)
    #     178         indexer = self._get_setitem_indexer(key)
    # --> 179         self._setitem_with_indexer(indexer, value)
    #     180 
    #     181     def _has_valid_type(self, k, axis):
    # 
    # /opt/anaconda-3/anaconda3/lib/python3.6/site-packages/pandas/core/indexing.py in _setitem_with_indexer(self, indexer, value)
    #     561                     value = np.array(value, dtype=object)
    #     562                     if len(labels) != value.shape[1]:
    # --> 563                         raise ValueError('Must have equal len keys and value '
    #     564                                          'when setting with an ndarray')
    #     565 
    # 
    # ValueError: Must have equal len keys and value when setting with an ndarray
    
  • 参考方案

    我喜欢这个

    d = pd.concat([
        df[['mass', 'type']],
        pd.DataFrame(df.pos.tolist(), df.index, ['x', 'y', 'z']),
        pd.DataFrame(df.vel.tolist(), df.index, ['x', 'y', 'z'])
    ], axis=1, keys=['Scalar', 'Position', 'Velocity'])
    
    d
    
      Scalar      Position         Velocity        
        mass type        x   y   z        x   y   z
    0    1.1    1        1   2   3        1   2   3
    1    2.2    2        4   5   6        4   5   6
    2    3.3    1        7   8   9        7   8   9
    3    4.4    1       10  11  12       10  11  12
    4    5.5    3       13  14  15       13  14  15
    

    您可以轻松地从顶层访问

    d.Velocity
    
        x   y   z
    0   1   2   3
    1   4   5   6
    2   7   8   9
    3  10  11  12
    4  13  14  15
    

    或做数学

    (d.Velocity + d.Position).div(d.Scalar.mass, axis=0)
    
              x         y         z
    0  1.818182  3.636364  5.454545
    1  3.636364  4.545455  5.454545
    2  4.242424  4.848485  5.454545
    3  4.545455  5.000000  5.454545
    4  4.727273  5.090909  5.454545
    

    而且您仍然可以轻松访问适当的Numpy数组

    d.Position.values
    
    array([[ 1,  2,  3],
           [ 4,  5,  6],
           [ 7,  8,  9],
           [10, 11, 12],
           [13, 14, 15]])
    

    R'relaimpo'软件包的Python端口 - python

    我需要计算Lindeman-Merenda-Gold(LMG)分数,以进行回归分析。我发现R语言的relaimpo包下有该文件。不幸的是,我对R没有任何经验。我检查了互联网,但找不到。这个程序包有python端口吗?如果不存在,是否可以通过python使用该包? python参考方案 最近,我遇到了pingouin库。

    Python ThreadPoolExecutor抑制异常 - python

    from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED def div_zero(x): print('In div_zero') return x / 0 with ThreadPoolExecutor(max_workers=4) as execut…

    在返回'Response'(Python)中传递多个参数 - python

    我在Angular工作,正在使用Http请求和响应。是否可以在“响应”中发送多个参数。角度文件:this.http.get("api/agent/applicationaware").subscribe((data:any)... python文件:def get(request): ... return Response(seriali…

    Python exchangelib在子文件夹中读取邮件 - python

    我想从Outlook邮箱的子文件夹中读取邮件。Inbox ├──myfolder 我可以使用account.inbox.all()阅读收件箱,但我想阅读myfolder中的邮件我尝试了此页面folder部分中的内容,但无法正确完成https://pypi.python.org/pypi/exchangelib/ 参考方案 您需要首先掌握Folder的myfo…

    python JSON对象必须是str,bytes或bytearray,而不是'dict - python

    在Python 3中,要加载以前保存的json,如下所示:json.dumps(dictionary)输出是这样的{"('Hello',)": 6, "('Hi',)": 5}当我使用json.loads({"('Hello',)": 6,…