【发布时间】:2019-05-18 01:17:26
【问题描述】:
我创建了许多非常简单的函数,我想将它们应用于 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'])
有趣的是,将这个数据集放在一起 - 我意识到只有当我的数据中有空值时才会发生错误 - 注意这包括索引的一级中的空值。这里的索引合法地为空,即这不是数据中的错误。
【问题讨论】:
-
您能提供一个数据框样本吗?确保您的错误在这里可以重现,并且那些试图帮助解决您的问题的人拥有所有必要的信息。
-
嗨 Rahlf23,我已经编辑以包含一个示例数据集 - 这现在让我相信问题是由于索引的一级中的空值 - 但鉴于可能是这种情况,怎么能我规避了错误?
-
嗨!您的示例代码不起作用,因为未定义
idx。但是,似乎确实必须有更好的方法来对数据框进行子集化。您能否告诉我您要选择哪个子集以及为什么?我想我们可以更好地帮助你 -
另外,
journey_offset是什么?请确保您的数据和代码可在我们的空 Python 环境中编译和运行。见minimal reproducible example。 -
这是XY problem 的尖叫声。您应该尽量避免使用 Pandas 完全使用
for循环。如果您通过minimal reproducible example 分享(可能在一个新问题中)您想要实现的目标,您更有可能找到一个好的解决方案。
标签: python pandas dataframe lambda slice