熊猫数据框组/块的标准化(如何快速插入行)

时间:2019-08-05 19:39:51

标签: python-3.x pandas dataframe pandas-groupby

我有“对象”(用表中的某些行分别表示),这些对象在多行中描述。但是问题是,对象有时会丢失行。我的目标是要有一个DataFrame,其中每个对象具有相同数量的行(相同的形状),而对象的缺失行将被空行填充。

例如:

对象1

O-ID | key 1 | key 2 | ... | key N  | value 1 | value 2 | value N
   0 | A 11  | A 21  | ... | key N1 |         |         | 
   0 | A 13  | A 23  | ... | key N3 |         |         | 
   0 | A 16  | A 26  | ... | key N6 |         |         | 

对象2

 O-ID | key 1 | key 2 | ... | key N  | value 1 | value 2 | value N
    1 | A 12  | A 22  | ... | key N2 |         |         | 
    1 | A 13  | A 23  | ... | key N3 |         |         | 
    1 | A 14  | A 24  | ... | key N4 |         |         |

“ O-ID”是对象ID。我们可以看到共有6种不同的行。最后,我希望每个对象都具有全部6行。 key 1 .. key-N是在键值对(值1 ...值N)意义上的键。

结果应如下所示:

对象1:

O-ID | key 1 | key 2 | ... | key N  | value 1 | value 2 | value N
   0 | A 11  | A 21  | ... | key N1 |         |         | 
   0 | A 12  | A 22  | ... | key N2 | Null    | Null    | Null
   0 | A 13  | A 23  | ... | key N3 |         |         | 
   0 | A 14  | A 24  | ... | key N4 | Null    | Null    | Null
   0 | A 15  | A 25  | ... | key N5 | Null    | Null    | Null
   0 | A 16  | A 26  | ... | key N6 |         |         | 

对象2:

O-ID | key 1 | key 2 | ... | key N  | value 1 | value 2 | value N
   1 | A 11  | A 21  | ... | key N1 | Null    | Null    | Null
   1 | A 12  | A 22  | ... | key N2 |         |         | 
   1 | A 13  | A 23  | ... | key N3 |         |         | 
   1 | A 14  | A 24  | ... | key N4 |         |         | 
   1 | A 15  | A 25  | ... | key N5 | Null    | Null    | Null
   1 | A 16  | A 26  | ... | key N6 | Null    | Null    | Null

除了使用缓慢的for循环外,我不知道该怎么做...

您知道一种更好/更快的方法来找出丢失的行以及如何插入“空”行吗?

我已经想到了按“ O-ID”对它们进行分组,然后在组上使用映射的想法。但是,如何快速以正确的顺序插入“空”行?

我正在使用最新的熊猫版本和最新的python 3

1 个答案:

答案 0 :(得分:1)

首先,我们根据结果数据帧res中所需的所有键创建一个This doc。然后,我们使用新的多索引multiindex将数据框{在最后一步,我们将键元组转换回单独的列,并对列进行重新排序并根据需要对行进行排序。

import pandas as pd

df = pd.DataFrame( {'O_ID': [0,0,0,1,1,1,2],
                    'key_1': ['A11', 'A13', 'A16', 'A12', 'A13', 'A14', 'A15'],
                    'key_2': ['A21', 'A23', 'A26', 'A22', 'A23', 'A24', 'A25'],
                    'key_n': ['key N1', 'key N3', 'key N6', 'key N2', 'key N3', 'key N4', 'key N5'],
                    'value_1': [11,12,13,14,15,16,17],
                    'value_2': [21,22,23,24,25,26,27],
                    'value_n': [121,122,123,124,125,126,127]
                    })

keycols = [c for c in df.columns if c.startswith('key')]
valcols = [c for c in df.columns if c.startswith('value')]

# create multiindex of all combinations of O_ID and key tuples
keys = df[keycols].apply(tuple, axis=1)
idx = pd.MultiIndex.from_product([df.O_ID.unique(), keys.unique()], names=['O_ID','key_tuples'])

# set index of O_ID and key tuples and reindex with new multiindex
res = df.set_index(['O_ID',keys]).drop(columns=keycols)
res = res.reindex(idx).reset_index()

# split key tuples back into individual columns and reorder/sort as needed
res = pd.DataFrame(res.key_tuples.to_list(), index=res.index, columns=keycols).join(res).drop(columns=['key_tuples'])
res = res.reindex(columns=['O_ID']+keycols+valcols).sort_values(['O_ID']+keycols)

结果:

    O_ID key_1 key_2   key_n  value_1  value_2  value_n
0      0   A11   A21  key N1     11.0     21.0    121.0
3      0   A12   A22  key N2      NaN      NaN      NaN
1      0   A13   A23  key N3     12.0     22.0    122.0
4      0   A14   A24  key N4      NaN      NaN      NaN
5      0   A15   A25  key N5      NaN      NaN      NaN
2      0   A16   A26  key N6     13.0     23.0    123.0
6      1   A11   A21  key N1      NaN      NaN      NaN
9      1   A12   A22  key N2     14.0     24.0    124.0
7      1   A13   A23  key N3     15.0     25.0    125.0
10     1   A14   A24  key N4     16.0     26.0    126.0
11     1   A15   A25  key N5      NaN      NaN      NaN
8      1   A16   A26  key N6      NaN      NaN      NaN
12     2   A11   A21  key N1      NaN      NaN      NaN
15     2   A12   A22  key N2      NaN      NaN      NaN
13     2   A13   A23  key N3      NaN      NaN      NaN
16     2   A14   A24  key N4      NaN      NaN      NaN
17     2   A15   A25  key N5     17.0     27.0    127.0
14     2   A16   A26  key N6      NaN      NaN      NaN

(我必须添加一个第三个对象,其键号为A15,否则从您的样本数据中不清楚该键的来源,即该方法使用了所有 existing 键。如果您知道所有预先输入键值,并希望使用这些键构建结果数据框,无论它们是否出现在输入数据框中,那么您都可以根据这些已知键值而不是输入数据中存在的唯一键来创建多索引)< / p>