【问题标题】:Iteration with for loop using round returns "TypeError: 'int' object is not callable"使用循环迭代循环返回“TypeError:'int'对象不可调用”
【发布时间】:2022-02-21 17:50:15
【问题描述】:

我有一个巨大的df,看起来像这样:

date stock1 stock2 stock3 stock4 stock5 stock6 stock7 stock8 stock9 stock10
10/20 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 0.9
11/20 0.8 0.9 0.3 0.4 0.3 0.5 0.3 0.2 0.4 0.1
12/20 0.3 0.6 0.9 0.5 0.6 0.7 0.8 0.7 0.9 0.1

我想为每一行找出股票价值高 20% 和低 20%。输出应该是:

date higher lower
10/20 stock9, stock 10 stock1, stock 2
11/20 stock1, stock 2 stock8, stock 10
12/20 stock3, stock 9 stock1, stock 10

我的代码现在看起来像这样:

l= df.count(1)
rank = pd.DataFrame()
for i in len(l):
      rank[i, "winners"] = df.apply(lambda x: x.nlargest(round(l[i-1]*0.2).index.tolist(), axis=1)
      rank[i, "losers"] = df.apply(lambda x: x.nsmallest(round(l[i-1]*0.2).index.tolist(), axis=1)

我收到错误“TypeError: 'int' object is not callable”。我检查了 l 的 dtype:频率:M,长度:344,dtype:float64。 我做错了什么?

【问题讨论】:

  • df(lambda x: 有错别字,需要df.apply(lambda x:
  • 我刚看到我并在帖子中更正。不过,我的错字不正确。
  • 范围(len(l))...
  • 和以前一样的错误

标签: python pandas for-loop rounding


【解决方案1】:

用途:

df = pd.DataFrame({'stock1':range(10), 'stock2':range(10,20), 'stock3':range(10,20), 'stock4':range(10,20), 'stock5':range(50,60)})

colnum = int(.2*len(df.columns))
df.apply(lambda x: x.nlargest(colnum).index.tolist(), axis=1)

输入df:

输出:

根据您的评论:

df = pd.DataFrame({f'stock{i}':np.random.randint(1,10,10) for i in range(2000)})
colnum = int(.2*len(df.columns))
df.apply(lambda x: x.nlargest(colnum).index.tolist(), axis=1)

输入 df 2000 列:

输出:

基于其他评论,可能是 nans:

df = pd.DataFrame({f'stock{i}':np.random.randint(1,10,10) for i in 

range(10)})
df2 = pd.DataFrame({f'stock{i}':np.random.randint(1,10,1) for i in range(7)})
df3 = df.append(df2)
df3 = df3.astype(np.float64)
df3.apply(lambda x: x.nlargest(int(.2*np.sum([1 for y in x if not np.isnan(y)]))).index.tolist(), axis=1)

输入df:

输出:

稍微好一点:

df3.apply(lambda x: x.nlargest(int(.2*x.notna().sum())).index.tolist(), axis=1)

【讨论】:

  • 我的真实数据集中有超过 2000 只股票,所以我无法应用。
  • 为什么不能?有什么问题?
  • 在建议代码的第一行,我必须写下每只股票的名称。此外,我的输出 df 中需要有 2 列(“赢家”和“输家”)。
  • 对于你提到的第一个问题:这只是一个例子。你不需要做第一行,因为你事先有 df 。对于第二个,只需用 nsmallest 重复最后一行。
  • 在代码中,对于输出中的每个系列,我们将在输出中包含“列号”股票。但这不是我需要的。在我的原始数据集中,df 每行的观察次数彼此不同。因此,例如,具有 100 个 obs 的行在输出中将有 20 个 obs (0.2*100)。具有 150 个 obs 的行将在输出中有 30 个 obs。这就是我使用 for 循环的原因。
【解决方案2】:

对新列使用DataFrame.assign

df1 = df.set_index('date')
i= int(round(len(df1.columns)*0.2))

df1 = df1.assign(winners = df1.apply(lambda x: x.nlargest(i).index.tolist(), axis=1),
                 losers = df1.apply(lambda x: x.nsmallest(i).index.tolist(), axis=1))
     
rank = df1[['winners','losers']].reset_index()                             
print (rank)
    date            winners             losers
0  10/20  [stock9, stock10]   [stock1, stock2]
1  11/20   [stock2, stock1]  [stock10, stock8]
2  12/20   [stock3, stock9]  [stock10, stock1]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多