我想使用python / pandas / numpy访问一个数组(df2)(实际上是一个pandas数据帧),以便根据条件语句索引到另一个数组(df)中,并在附加标签时构建一个新的数组(New)
这是我要为正在处理的类项目构建的数据清理例程。通常,我会使用Matlab来解决此类问题,但很遗憾,我现在没有访问权限。到目前为止,我已经尝试了以下代码:1)创建一个称为df的随机值数据框。 2)创建第二个数据框,该数据框是df1的五行(称为df2)的增量百分比。 3)查看df2中的所有值,并使用条件语句从这些值中创建一个名为New的新数据框。 New由df切片以及基于百分比变化的标签组成(标签在循环中使用if语句创建,如下所示)。另外,请注意,在df中定义切片的索引与df2中的索引不同,但通过简单的移位即可关联。
import pandas as pd
import numpy as np
import matplotlib as plt
df = pd.DataFrame(np.random.randn(100, 10)) #Create random dataframe
df
df2=df.pct_change(5) #Create a related dataframe df2
New=[] #Create an empty dataframe to build my new dataframe
it=np.nditer(df2, flags=['multi_index'])
while not it.finished:
i=it.multi_index(0,0)
k=it.multi_index(0,1)
ii=i-10
end=ii-5
if df2.iloc[i,k]>1:
New=df.iloc[ii:end,k].append(1, ignore_index=true)
elif df2.iloc[i,k]>.5:
New=df.iloc[ii:end,k].append(2, ignore_index=true)
elif df2.iloc[i,k]>.25:
New=df.iloc[ii:end,k].append(3, ignore_index=true)
elif df2.iloc[i,k]>0:
New=df.iloc[ii:end,k].append(4, ignore_index=true)
elif df2.iloc[i,k]>-.05:
New=df.iloc[ii:end,k].append(5, ignore_index=true)
else:
New=[]
Labeled=New
Final=Labeled.append(New, ignore_index=true)
it.iternext()
我期望得到一个名为New的数组,该数组具有6行和950列,其中第6行是标签,第1-5行是df1的切片。运行代码时得到的输出是:
--------------------------------------------------------------------
-------
TypeError Traceback (most recent
call last)
<ipython-input-7-3743c76c2bd6> in <module>()
10 it=np.nditer(df2, flags=['multi_index'])
11 while not it.finished:
---> 12 i=it.multi_index(0,0)
13 k=it.multi_index(0,1)
14 ii=i-10
TypeError: 'tuple' object is not callable
很明显,我对multi_index的使用不太正确。在阅读nditter手册后,我的期望是它。multi_index将是一个1X2数组,然后我可以用它来关联两个数据帧之间的索引并用于创建df切片。另外,我知道这种类型的迭代在Python中是不理想的,因为它很慢,但是由于索引是偏移的并且创建的最终数据帧与两个都不相同,因此我无法找到一种矢量化此例程的方法。输入数组。无论如何,任何指针将不胜感激。谢谢!
答案 0 :(得分:1)
看看基本的多重索引https://www.numpy.org/devdocs/reference/arrays.nditer.html#tracking-an-index-or-multi-index
In [109]: it = np.nditer(np.ones(12).reshape(3,4), flags=['multi_index'])
In [110]: with it:
...: while not it.finished:
...: print(it.multi_index)
...: it.iternext()
...:
(0, 0)
(0, 1)
...
(2, 2)
(2, 3)
请注意,it.multi_index
是一个元组。这就是错误的直接来源
i=it.multi_index(0,0)
(0,0)
是用于调用函数而非索引的Python语法(与MATLAB用法相反)。另外,multi_index
不是二维数组,因此[0,0]
也将无效。
这应该可以解决当前的问题:
11 while not it.finished:
12 i=it.multi_index[0]
13 k=it.multi_index[1]
# i, k = it.multi_index # using unpacking
14 ii=i-10
我想知道为什么您要使用nditer
。我从未见过将它应用于数据框。
In [119]: df2.shape
Out[119]: (100, 10)
In [120]:
In [120]: it = np.nditer(df2, flags=['multi_index'])
In [121]: it.multi_index
Out[121]: (0, 0)
In [122]: it.iternext()
Out[122]: True
In [123]: it.multi_index
Out[123]: (1, 0)
In [124]: it.iternext()
Out[124]: True
In [125]: it.multi_index
Out[125]: (2, 0)
如果我让它运行到最后,最后一个元组将是(99,9)。所以和做一样
for i,k in np.ndindex(df2.shape):
....
但这并不是说太多,因为ndindex
是在Python级别使用nditer
的少数几个地方之一。 https://www.numpy.org/devdocs/reference/arrays.nditer.html中记录的nditer
主要是在cython
或其他编译代码中使用它的踏脚石。在Python级别上,它提供的速度不是很多,当然也不是任何速度。
或等效地:
for i in range(100):
for k in range(10):
# do stuff with i,k
另一个问题
New=[]
这是空的列表。我们经常通过增加列表来创建数组
alist = []
for ....:
alist.append(avalue)
arr = np.array(alist)
我不确定这些行:
New=df.iloc[ii:end,k].append(1, ignore_index=true)
这将为New
分配一个新值,以替换以前的任何值。我不熟悉pandas
df []。append(...). If it were the numpy
np.append(new,x)`,我会尖叫流血的谋杀案。
我更专注于numpy
,但我认为有更好的方法可以遍历数据帧。 nditer
不是一个好的通用迭代工具。 pandas
个人似乎经常使用apply
。