【发布时间】:2021-07-14 15:56:29
【问题描述】:
我正在尝试编写一个函数,该函数将 2D 方形 DataFrame 和索引列表作为输入,并返回一个包含行索引和列索引总和的新 DataFrame。 这里有一个例子的代码:
import pandas as pd
import numpy as np
def cluster_sum(matrix, cluster):
matrix[tuple(cluster)] = matrix[cluster].sum(axis=1)
matrix = matrix.drop(cluster, axis=1)
matrix = matrix.append(pd.Series(matrix.loc[cluster, :].sum(axis=0), name=tuple(cluster)))
matrix = matrix.drop(cluster, axis=0)
return matrix
idx = ['a', 'b', 'c']
sample_df = pd.DataFrame(np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]]), index=idx, columns=idx)
print(sample_df)
当前数据帧:
a b c
a 0 1 1
b 1 0 1
c 1 1 0
我定义了一个集群并应用 cluster_sum:
cluster = ['a', 'b']
new_df = cluster_sum(sample_df, cluster)
print(new_df)
结果如我所愿:
c (a, b)
c 0 2
(a, b) 2 2
现在问题来了:如果我尝试选择新行(a,b):
print(new_df.loc[('a', 'b'), :])
它给了我以下错误:
Traceback (most recent call last):
File "C:\Users\damia\PycharmProjects\logistic-tool\try2.py", line 23, in <module>
print(new_df.loc[('a', 'b'), :])
File "C:\Users\damia\PycharmProjects\print\venv\lib\site-packages\pandas\core\indexing.py", line 925, in __getitem__
return self._getitem_tuple(key)
File "C:\Users\damia\PycharmProjects\print\venv\lib\site-packages\pandas\core\indexing.py", line 1109, in _getitem_tuple
return self._getitem_tuple_same_dim(tup)
File "C:\Users\damia\PycharmProjects\print\venv\lib\site-packages\pandas\core\indexing.py", line 806, in _getitem_tuple_same_dim
retval = getattr(retval, self.name)._getitem_axis(key, axis=i)
File "C:\Users\damia\PycharmProjects\print\venv\lib\site-packages\pandas\core\indexing.py", line 1153, in _getitem_axis
return self._getitem_iterable(key, axis=axis)
File "C:\Users\damia\PycharmProjects\print\venv\lib\site-packages\pandas\core\indexing.py", line 1093, in _getitem_iterable
keyarr, indexer = self._get_listlike_indexer(key, axis)
File "C:\Users\damia\PycharmProjects\print\venv\lib\site-packages\pandas\core\indexing.py", line 1314, in _get_listlike_indexer
self._validate_read_indexer(keyarr, indexer, axis)
File "C:\Users\damia\PycharmProjects\print\venv\lib\site-packages\pandas\core\indexing.py", line 1374, in _validate_read_indexer
raise KeyError(f"None of [{key}] are in the [{axis_name}]")
KeyError: "None of [Index(['a', 'b'], dtype='object')] are in the [index]"
我做了一些研究,我确定问题出在元组形式的索引上。我认为熊猫希望我在新行中使用 MultiIndex,并且最好在列中也使用 MultiIndex,但我不熟悉 MultiIndex。我尝试创建一个具有 MultiIndex 名称的 Series,然后将其添加到 DataFrame,但我认为创建 MultiIndex Series 是不可能的,所以我在这里寻求建议。
编辑:将索引放在方括号内,如下所示:new_df.loc[[('a', 'b')], :]
对我来说不是一个好的解决方案,因为我需要检查索引是否是元组,这不是一个有效的解决方案。像这样的:
for i in new_df.index:
if type(i) is tuple:
print(new_df.loc[[i], :])
else:
print(new_df.loc[i, :])
它会起作用,但必须有一个更有效的解决方案......
【问题讨论】:
-
索引列表 (
cluster) 的长度可以超过 2 项吗?您在问题中提到MultiIndex;如果集群大小可以超过 2,或者如果您打算多次运行它,那么您当前的方法或使用MultiIndex的任何替代实现都不能是免费的if..else(因为这样各种行将具有任意深度索引) .对上下文进行更多澄清可能会有所帮助。
标签: python pandas dataframe tuples multi-index