Python Pandas - 从数据框创建一个数组或矩阵进行乘法运算
Posted
技术标签:
【中文标题】Python Pandas - 从数据框创建一个数组或矩阵进行乘法运算【英文标题】:Python Pandas - from data frame create an array or matrix for multiplication 【发布时间】:2018-06-11 18:37:00 【问题描述】:我发现了这篇之前的帖子,它让我很接近。 how-to-convert-a-pandas-dataframe-subset-of-columns-and-rows-into-a-numpy-array
但是,我需要遍历数据框并从列“b”到“j”创建一个 3x3 数组(或矩阵),而不是根据第三个中的值创建一个包含两列的数组(或矩阵) ' 对于 'a' 中每个正确匹配的值。
dft = pd.DataFrame('a' : ['NW' ,'NW', 'SL', 'T'],
'b' : [1,2,3,4],
'c' : [5,6,7,8],
'd' : [11,12,13,14],
'e' : [9,10,11,12],
'f' : [4,3,2,1],
'g' : [15,14,13,12],
'h' : [13,14,15,16],
'i' : [5,4,3,2],
'j' : [9,8,7,6]
)
print(dft)
a b c d e f g h i j
0 NW 1 5 11 9 4 15 13 5 9
1 NW 2 6 12 10 3 14 14 4 8
2 SL 3 7 13 11 2 13 15 3 7
3 T 4 8 14 12 1 12 16 2 6
我想要的是 2 个单独的数组,每个 NW
1 个
[[ 1 5 11]
[ 9 4 15]
[13 5 9]]
[[ 2 6 12]
[10 3 14]
[14 4 8]]
我尝试了以下方法并收到了一个非常丑陋的错误。该代码是基于原帖的尝试。
dft.loc[dft['a'] == 'NW',['b', 'c', 'd'], ['e', 'f', 'g'], ['h', 'i', 'j']].values
这是错误-
IndexingError Traceback(最近调用 最后)在() ----> 1 dft.loc[dft['a'] == 'NW',['b', 'c', 'd'], ['e', 'f', 'g'], ['h', 'i', 'j']].values
D:\Applications\Anaconda\lib\site-packages\pandas\core\indexing.py 在 getitem(self, key) 1323 except (KeyError, IndexError): 1324 pass -> 1325 return self._getitem_tuple(key) 1326 else: 1327 key = com._apply_if_callable(key, self.obj)
D:\Applications\Anaconda\lib\site-packages\pandas\core\indexing.py 在 _getitem_tuple(自我,tup) 839 840 # 没有多索引,所以验证所有的索引器 --> 841 self._has_valid_tuple(tup) 842 第843章 #836
D:\Applications\Anaconda\lib\site-packages\pandas\core\indexing.py 在 _has_valid_tuple(自我,密钥) 186 for i, k in enumerate(key): 187如果我> = self.obj.ndim: --> 188 raise IndexingError('Too many indexers') 189 如果不是 self._has_valid_type(k, i): 190 raise ValueError("基于位置的索引只能有 [%s]"
IndexingError: 索引器过多
想法?我如此接近,却又如此诱人。
我不知道如何格式化错误代码 - 有什么帮助可以清除它吗?【问题讨论】:
【参考方案1】:你可以在没有循环的情况下做到这一点
a = df.loc[df['a'] == 'NW', 'b':'j']
n = a.shape[0]
new_a = a.values.reshape(n,3,3)
你得到
array([[[ 1, 5, 11],
[ 9, 4, 15],
[13, 5, 9]],
[[ 2, 6, 12],
[10, 3, 14],
[14, 4, 8]]])
【讨论】:
我喜欢这个解决方案,但它假设“a”列中只有 2 行带有“NW”。您是否知道是否有一种方法可以在一行中执行此操作,而无需对reshape()
中的第一个值 (2) 进行硬编码?
@OriolMirosa,你是对的。查看我的解决方案的编辑
不错!我猜你甚至可以删除第二行,让第三行简单地写成new_a = a.values.reshape(a.shape[0], 3, 3)
,对吧?
@OriolMirosa,是的。为了清楚起见,我刚刚创建了一个变量 n
在这里我想这会很难;)感谢这个董事会!【参考方案2】:
我不是 100% 确定你在追求什么,但也许这会有所帮助:
new_arrays = []
for index, row in dft.iterrows():
if row['a'] == 'NW':
new_arrays.append(row[1:].values.reshape(3, 3))
itertuples()
,按照 cmets 的要求:
for index, row in enumerate(dft.itertuples(), 1):
if row[1] == 'NW':
new_arrays.append(np.array(row[2:]).reshape(3, 3))
现在您在new_arrays
中拥有了两个数组,您可以将它们一起打印或单独访问:
new_arrays[0]
array([[1, 5, 11],
[9, 4, 15],
[13, 5, 9]], dtype=object)
new_arrays[1]
array([[2, 6, 12],
[10, 3, 14],
[14, 4, 8]], dtype=object)
【讨论】:
这在我的示例数据中非常有效。但是在用我的真实数据进行尝试时,我只是做了if row ['Code'] == 'Network'
,它告诉我Code' is not defined
。我错过了什么?其余数据完全相同,只是原始数据中的列更多。另外,我在 Pandas 文档中读到 iterrows
不好,所以使用 itertuples
。我试过了,它说ValueError: too many values to unpack (expected 2)
。
您的数据框似乎没有名为 Code
的列。是这样吗?至于itertuples()
,这让事情变得有点尴尬,但我在答案中添加了解决方案。
执行dft.columns
会返回Code\n
。添加了 \n 并且它起作用了。猜测是因为该列是文本??????
\n
是换行符,您可能需要在dft.colums
中清除它以避免将来出现问题。我很高兴它现在可以工作了。以上是关于Python Pandas - 从数据框创建一个数组或矩阵进行乘法运算的主要内容,如果未能解决你的问题,请参考以下文章