将稀疏数据帧转换为密集数据帧

时间:2016-05-13 09:47:37

标签: python pandas merge

我将稀疏数据存储在数据帧中:

df = pd.DataFrame({'a':[1,3,5], 'b':[2,5,5], 'data':np.random.randn(3)})

a   b   data
0   1   2   -0.824022
1   3   5   0.503239
2   5   5   -0.540105

由于我关心空数据,实际数据如下所示:

true_df

    a   b   data
0   1   1   NaN
1   1   2   -0.824022
2   1   3   NaN
3   1   4   NaN
4   1   5   NaN
5   2   1   NaN
6   2   2   NaN
7   2   3   NaN
8   2   4   NaN
9   2   5   NaN
10  3   1   NaN
11  3   2   NaN
12  3   3   NaN
13  3   4   NaN
14  3   5   0.503239
15  4   1   NaN
16  4   2   NaN
17  4   3   NaN
18  4   4   NaN
19  4   5   NaN
20  5   1   NaN
21  5   2   NaN
22  5   3   NaN
23  5   4   NaN
24  5   5   -0.540105

我的问题是如何构建true_df?我希望有一些方法可以使用pd.concatpd.merge,也就是说,构造一个密集表形状的数据帧,然后加入两个数据帧,但不加入预期方式(列没有组合)。最终目标是转向a和b。

作为一个跟进因为我认为kinjo是正确的,为什么这只适用于整数而不适用于浮点数?使用:

import pandas as pd
import numpy as np

df = pd.DataFrame({'a':[1.0,1.3,1.5], 'b':[1.2,1.5,1.5], 'data':np.random.randn(3)})

### Create all possible combinations of a,b
newindex = [(b,a) for b in np.arange(1,df.b.max()+0.1, 0.1) for a in np.arange(1,df.a.max()+0.1,0.1)]

### Set the index as a,b and reindex
df.set_index(['a','b']).reindex(newindex).reset_index()

将返回:

    a   b   data
0   1.0 1.0 NaN
1   1.0 1.1 NaN
2   1.0 1.2 NaN
3   1.0 1.3 NaN
4   1.0 1.4 NaN
5   1.0 1.5 NaN
6   1.0 1.6 NaN
7   1.1 1.0 NaN
8   1.1 1.1 NaN
9   1.1 1.2 NaN
10  1.1 1.3 NaN
11  1.1 1.4 NaN
12  1.1 1.5 NaN
13  1.1 1.6 NaN
14  1.2 1.0 NaN
15  1.2 1.1 NaN
16  1.2 1.2 NaN
17  1.2 1.3 NaN
18  1.2 1.4 NaN
19  1.2 1.5 NaN
20  1.2 1.6 NaN
21  1.3 1.0 NaN
22  1.3 1.1 NaN
23  1.3 1.2 NaN
24  1.3 1.3 NaN
25  1.3 1.4 NaN
26  1.3 1.5 NaN
27  1.3 1.6 NaN
28  1.4 1.0 NaN
29  1.4 1.1 NaN
30  1.4 1.2 NaN
31  1.4 1.3 NaN
32  1.4 1.4 NaN
33  1.4 1.5 NaN
34  1.4 1.6 NaN
35  1.5 1.0 NaN
36  1.5 1.1 NaN
37  1.5 1.2 NaN
38  1.5 1.3 NaN
39  1.5 1.4 NaN
40  1.5 1.5 NaN
41  1.5 1.6 NaN
42  1.6 1.0 NaN
43  1.6 1.1 NaN
44  1.6 1.2 NaN
45  1.6 1.3 NaN
46  1.6 1.4 NaN
47  1.6 1.5 NaN
48  1.6 1.6 NaN

2 个答案:

答案 0 :(得分:1)

由于您打算转动ab,您可以使用

获取转化结果
import numpy as np
import pandas as pd
df = pd.DataFrame({'a':[1,3,5], 'b':[2,5,5], 'data':np.random.randn(3)})

result = pd.DataFrame(np.nan, index=range(1,6), columns=range(1,6))
result.update(df.pivot(index='a', columns='b', values='data'))
print(result)

产生

    1         2   3   4         5
1 NaN  0.436389 NaN NaN       NaN
2 NaN       NaN NaN NaN       NaN
3 NaN       NaN NaN NaN -1.066621
4 NaN       NaN NaN NaN       NaN
5 NaN       NaN NaN NaN  0.328880

答案 1 :(得分:1)

Reindex是一个简单的解决方案。与@ jezrael的解决方案类似,但不需要合并。

import pandas as pd
import numpy as np

df = pd.DataFrame({'a':[1,3,5], 'b':[2,5,5], 'data':np.random.randn(3)})

### Create all possible combinations of a,b
newindex = [(b,a) for b in range(1,df.b.max()+1) for a in range(1,df.a.max()+1)]

### Set the index as a,b and reindex
df.set_index(['a','b']).reindex(newindex)

如果您希望将数字计数作为整体索引,则可以重置索引。

如果您的索引是浮点you should use linspace and not arange

import pandas as pd
import numpy as np

df = pd.DataFrame({'a':[1.0,1.3,1.5], 'b':[1.2,1.5,1.5], 'data':np.random.randn(3)})

### Create all possible combinations of a,b
newindex = [(b,a) for b in np.linspace(a_min, a_max, a_step, endpoint=False) for a in np.linspace(b_min, b_max, b_step, endpoint=False)]

### Set the index as a,b and reindex
df.set_index(['a','b']).reindex(newindex).reset_index()