我正在使用Pandas表示来自调查的相当复杂的数据集。到目前为止,似乎具有多索引的一维变量系列最适合存储和处理这些数据。
每个变量名称由“路径”组成,以唯一标识该特定响应。这些路径长度各不相同。我试图弄清楚我是否误解了层次索引应该如何工作,或者如果我遇到了一个bug。看起来好像Pandas在将它们连接到数据集时将较短的索引“填充”到最大长度,并且在此过程中会破坏该值。
例如,此测试失败:
def test_dataframe_construction1(self):
case1 = pd.Series(True, pd.MultiIndex.from_tuples([
('a1', 'b1', 'c1'),
('a2', 'b2', 'c2', 'd1', 'e1'),
]))
case2 = pd.Series(True, pd.MultiIndex.from_tuples([
('a3', 'b3', 'c3'),
('a4', 'b4', 'c4', 'd2', 'e2'),
]))
df = pd.DataFrame({
'case1': case1,
'case2': case2
})
logger.debug(df)
self.assertEquals(df['case1'].loc['a1'].any(), True)
打印出来:
a1 b1 c1 nan nan NaN NaN
a2 b2 c2 d1 e1 True NaN
a3 b3 c3 nan nan NaN NaN
a4 b4 c4 d2 e2 NaN True
有趣的是,用空字符串而不是NaN填充“较短”的索引会导致我期望的行为:
def test_dataframe_construction2(self):
case1 = pd.Series(True, pd.MultiIndex.from_tuples([
('a1', 'b1', 'c1', '', ''),
('a2', 'b2', 'c2', 'd1', 'e1'),
]))
case2 = pd.Series(True, pd.MultiIndex.from_tuples([
('a3', 'b3', 'c3', '', ''),
('a4', 'b4', 'c4', 'd2', 'e2'),
]))
df = pd.DataFrame({
'case1': case1,
'case2': case2
})
logger.debug(df)
self.assertEquals(df['case1'].loc['a1'].any(), True)
打印出来:
case1 case2
a1 b1 c1 True NaN
a2 b2 c2 d1 e1 True NaN
a3 b3 c3 NaN True
a4 b4 c4 d2 e2 NaN True
我在这里缺少什么?谢谢!
答案 0 :(得分:1)
避免在索引中使用NaN。除此之外,您还需要一个不同的模式来表示路径/案例/数据之间的关系。您需要可变数量的MultiIndex级别的事实是一个强烈的提示,并且案例列看起来只使用几个路径。我会将节点,路径和案例数据拆分为单独的DataFrame。在下面的示例中,我将展示如何表示case1的第一个路径。
import pandas as pd
from itertools import product
node_names = ['%s%d' % t for t in product('abcd', range(1, 5))]
nodes = pd.DataFrame({'node': node_names})
nodes.index.name = 'id'
path_nodes = pd.DataFrame({'path_id': [0, 0, 0],
'node_id': [0, 4, 8],
'position':[0, 1, 2]})
data = pd.DataFrame({'path_id': [0],
'case': [1],
'data': [True]})
In [113]: nodes
Out[113]:
node
id
0 a1
1 a2
2 a3
3 a4
4 b1
5 b2
6 b3
7 b4
8 c1
...
In [114]: path_nodes
Out[114]:
node_id path_id position
0 0 0 0
1 4 0 1
2 8 0 2
In [115]: data
Out[115]:
case data path_id
0 1 True 0