Pandas作业跳绳的有效方法

2024-03-28 19:37:17 发布

您现在位置:Python中文网/ 问答频道 /正文

一定有一个简单的方法,但我错过了。首先,想象一下Excel中的情况:

  1. 我有一个百分比变化栏。(假设A列)
  2. 在下一列(B)中,我想创建一个基于百分比变化的以1000开头的索引序列。在Excel中,我通过。 -将B1设置为1000 -将B2设置为公式=(1+A2)*B1 -向下复制列。很简单。

现在,我想对pandas做同样的事情,问题是以下代码导致目标数组变为NaN:

import pandas as pd
import numpy as np

df_source = pd.DataFrame(np.random.normal(0,.05,10), index=range(10), columns=['A'])

df_target = pd.DataFrame(index = df_source.index) 
df_target.loc[0,"A"] = 1000 # initialize target array to start at 1000

df_target["A"] = (1 + df_source) * df_target["A"].shift(1) # How to skip first row?

目标数组变为NaN,因为第一行试图引用“脱离dataframe”的值,所以整列返回NaN。

我意识到我可以用循环遍历行,跳过第一行,但是这非常慢,对于我将要执行的数据集或迭代的大小来说不实用。

必须有一种使用pandas/numpy数组函数的方法,但是告诉它跳过计算中的第一行。怎么做?我试过布尔索引,但没能成功,也许有办法告诉熊猫跳过NaN结果。。。但最好的方法似乎是一个限定符,上面写着“应用此代码,从第二行开始”

我错过了什么?

编辑:

看来我的问题比我意识到的还要严重。耶兹雷尔下面的回答解决了NA问题,但我想我对熊猫的逻辑感到困惑。我上面给出的代码不能工作,因为它不能按元素工作。例如,一个简单的例子:

seriesdf = pd.DataFrame(index = range(10))
seriesdf['A'] = 1
seriesdf['A'].ix[1:] = 1 + seriesdf['A'].shift(1)

给出结果

   A
0  1
1  2
2  2
3  2
4  2
5  2
6  2
7  2
8  2
9  2

不像我想象的那样是递增的计数。所以问题是,在pandas数据帧上进行逐行计算的最有效方法是什么?在这个应用程序中,速度很重要,所以我不希望在行之间进行交互。

新的python程序员正在尝试解决这个问题。我很感激能给我展示如何学习/解决这些问题的答案。谢谢您!


Tags: 方法代码sourcetargetdataframepandasdfindex
2条回答

我想我理解您的问题,在这些情况下,我通常会发现制作一个列表并将其附加到现有的数据帧更容易。当然,您可以先创建一个序列实例,然后进行计算。

new_series = [0]*len(df["A"])                 
new_series[0] = 1000                           

for i,k in enumerate(dataframe["A"].ix[1:]):   
    new_series[i] = (1 + k)*new_series[i-1]    

dataframe["B"] = pd.Series(new_series)         

IIRC,iloc在熊猫的未来构建中被弃用,取而代之的是ix

重新考虑问题后,可以在数据帧中使用lambda表达式作为元素

dataframe["B"] = [lambda row: (1 + dataframe["A"].ix[row])*dataframe["B"].ix[row-1]*len(dataframe["A"])
# Above: initiate "B" with a lambda expression that is as long as "A"

dataframe["B"].ix[0] = 1000
for i,k in enumerate(dataframe["B"].ix[1]):
    dataframe["B"].ix[i] = k(row=i)

我正试图想办法使用for循环来解决这个问题,但无法找到从何处获取行号的方法。

希望这有帮助。

IIUC您可以跳过df_sourceA的第一行,方法是选择所有行而不首先选择^{}

df_target["A"].ix[1:] = df_source['A'].ix[1:] + 1
print df_target
             A
0  1000.000000
1     0.988898
2     0.986142
3     1.009979
4     1.005165
5     1.101116
6     0.992312
7     0.962890
8     1.051340
9     1.009750

或者你认为:

import pandas as pd
import numpy as np

df_source = pd.DataFrame(np.random.normal(0,.05,10), index=range(10), columns=['A'])
print df_source
          A
0  0.039965
1  0.060821
2 -0.079238
3 -0.129932
4  0.002196
5 -0.003721
6 -0.008358
7  0.014104
8 -0.022905
9  0.014793

df_target = pd.DataFrame(index = df_source.index) 
#all A set to 1000
df_target["A"] = 1000 # initialize target array to start at 1000
print df_target
      A
0  1000
1  1000
2  1000
3  1000
4  1000
5  1000
6  1000
7  1000
8  1000
9  1000
df_target["A"] = (1 + df_source["A"].shift(-1))* df_target["A"]
print df_target
             A
0  1060.820882
1   920.761946
2   870.067878
3  1002.195555
4   996.279287
5   991.641909
6  1014.104402
7   977.094961
8  1014.793488
9          NaN

编辑:

也许你需要^{}

df_target["B"]  = 2
df_target["C"] = df_target["B"].cumsum()

df_target["D"] = df_target["B"] + df_target.index
print df_target
             A  B   C   D
0  1041.003000  2   2   2
1  1013.817000  2   4   3
2   948.853000  2   6   4
3  1031.692000  2   8   5
4   970.875000  2  10   6
5  1011.095000  2  12   7
6  1053.472000  2  14   8
7   903.765000  2  16   9
8  1010.546000  2  18  10
9     0.010546  2  20  11

相关问题 更多 >