子集在循环中时,Python函数不适用于Pandas Dataframe

时间:2018-12-17 16:23:06

标签: python pandas dataframe lambda slice

我创建了许多非常简单的函数,希望将它们应用于pandas DataFrame。例如:

def dir_flag(start, end):
   try:
      if start < end:
         return '+'
      else:
         return '-'
   except:
      return 'NA'

我已经将一个csv文件导入到名为“ mydata”的DataFrame中,并且可以应用我的功能:

mydata['direction'] = mydata.apply(lambda x: dir_flag(x['START_NODE'], x['END_NODE']), axis=1)

这很好。但是,当我尝试将此功能-或类似的功能应用于作为“ mydata”子集创建的Pandas DataFrame时,出现以下错误:ValueError: Wrong number of items passed 2, placement implies 0。仅供参考mydata包含3级多索引。

子设置发生在以下循环中:

idx = pd.IndexSlice

idx1_levels = mydata.index.unique(level='idx_level1').tolist()

for x in idx1_levels:
   idx1_subset = mydata.loc[idx[x], ['START_NODE','END_NODE']]
   idx2_levels = idx1_subset.index.unique(level='idx_level2').tolist()
   for y in idx2_levels:

       idx2_subset = idx1_subset.loc[idx[y]]

       idx3_subset = idx2_subset.loc[idx[slice(None), 1.0], ['START_NODE','END_NODE']]

       idx3_subset['direction'] = journey_offset.apply(lambda a: dir_flag(a['START_NODE'], a['END_NODE']), axis=1)

似乎是由idx3_subset = idx2_subset.loc[idx[slice(None), 1.0], ['START_NODE','END_NODE']]语句引起的,因为我可以很高兴地将函数应用于idx2_subset

请注意,我是Python的新手,我强烈怀疑有一种更好的方法来对原始DataFrame进行子设置(例如,可能使用groupby方法)。我很高兴收到有关如何改善整体子集的建议-但请提供任何答案,以解决为何此子集不起作用的具体问题,因为这将有助于增进我对Pandas DataFrames工作原理的理解。

读入的csv的简化版本是:

idx_level1|idx_level2|idx_level3|idx_level4|START_NODE|END_NODE
353386066294006|1142|2018-09-20T07:57:26Z|1|18260004567689|18260005575180
353386066294006|1142|2018-09-20T07:57:26Z|2|18260004567689|18260004240718
353386066294006|1142|2018-09-20T07:57:26Z|3|18260005359901|18260004567689
353386066294006|1142|2018-09-20T07:57:31Z|1|18260004567689|18260005575180
353386066294006|1142|2018-09-20T07:57:31Z|2|18260004567689|18260004240718
353386066294006|1142|2018-09-20T07:57:31Z|3|18260005359901|18260004567689
353386066294006|1142|2018-09-20T07:57:36Z|1|18260004567689|18260005575180
353386066294006|1142|2018-09-20T07:57:36Z|2|18260004567689|18260004240718
353386066294006|1142|2018-09-20T07:57:36Z|3|18260005359901|18260004567689
353386066736543|22|2018-04-17T07:08:23Z|||
353386066736543|22|2018-04-17T07:08:24Z|||
353386066736543|22|2018-04-17T07:08:25Z|||
353386066736543|22|2018-04-17T07:08:26Z|||
353386066736543|403|2018-07-02T16:55:07Z|1|18260004580350|18260005235340
353386066736543|403|2018-07-02T16:55:07Z|2|18260005235340|18260005141535
353386066736543|403|2018-07-02T16:55:07Z|3|18260005235340|18260005945439
353386066736543|403|2018-07-02T16:55:07Z|4|18260006215338|18260005235340
353386066736543|403|2018-07-02T16:55:07Z|5|18260004483352|18260005945439
353386066736543|403|2018-07-02T16:55:07Z|6|18260004283163|18260006215338
353386066736543|403|2018-07-02T16:55:01Z|1|18260004580350|18260005235340
353386066736543|403|2018-07-02T16:55:01Z|2|18260005235340|18260005141535
353386066736543|403|2018-07-02T16:55:01Z|3|18260005235340|18260005945439
353386066736543|403|2018-07-02T16:55:01Z|4|18260006215338|18260005235340
353386066736543|403|2018-07-02T16:55:01Z|5|18260004483352|18260005945439
353386066736543|403|2018-07-02T16:55:01Z|6|18260004283163|18260006215338

我用来读入的代码如下:

mydata = pd.read_csv('/myloc/my_simple_data.txt', sep='|', 
 dtype={'idx_level1': 'int',
        'idx_level2': 'int',
        'idx_level3': 'str',
        'idx_level4': 'float',
        'START_NODE': 'str',
        'END_NODE': 'str'},
 parse_dates = ['idx_level3'],
 index_col=['idx_level1','idx_level2','idx_level3','idx_level4'])

有趣的是,在将这个数据集放在一起时-我意识到只有在我的数据中包含空值时才会发生错误-注意,在一级索引中包含空值。此处的索引合法为空,即这不是数据错误。

1 个答案:

答案 0 :(得分:0)

因此,问题出在对其中一个级别包含空值的multiindex进行索引切片。因此,解决方案是将空值替换为常量:

mydata = pd.read_csv('/myloc/my_simple_data.txt', sep='|', 
 dtype={'idx_level1': 'int',
        'idx_level2': 'int',
        'idx_level3': 'str',
        'idx_level4': 'float',
        'START_NODE': 'str',
        'END_NODE': 'str'},
 parse_dates = ['time']);

mydata.idx_level4 = mydata.idx_level4.fillna(1.0)

mydata.set_index(['idx_level1','idx_level2','idx_level3','idx_level4'], inplace=True)

尽管这确实回答了问题,但要了解导致错误的具体原因并提供避免错误的方法-我仍然对为什么空值首先导致问题感到困惑。