for循环用于从数据帧计算

时间:2017-09-12 09:27:59

标签: python pandas dataframe

所以,我有一个文本文件,我已经变成了一个数据帧。我基本上只是试图遍历H和Z列的每个值,将它们各自平方,然后取平方根(换句话说就是毕达哥拉斯定理)。 I.E.

F = sqrt(H**2 + Z**2).

我的数据:(在变成熊猫数据框之后)

    H        D       Z
0   3235     6764    9546
1   1667     3455    7776
2   3555     3564    5433
3   2344     3333    8777
4   5666     3334    4444

这是一小部分数据。大约有1000个>这里的数据行。

代码:

import pandas as pd

#load data:

df=pd.read_table('example_data.txt', sep='\s+')

from math import sqrt
for x,y in df:
    F=sqrt(H**2+Z**2)
    print(F)

产生错误:

ValueError                                Traceback (most recent call last)
<ipython-input-34-1b1be5be91d0> in <module>()
        1 from math import sqrt
  ----> 2 for x,y in df:
        3     F=sqrt(H**2+Z**2)
        4     print(F)
        5 

        ValueError: too many values to unpack (expected 2)

就是这样。这是一个我觉得很容易的问题,但是一个Python初学者似乎无法解决。它基本上用2个变量重复计算多次。我已经看到它有1个变量而不是2个。

非常感谢任何帮助,

干杯!

3 个答案:

答案 0 :(得分:2)

您应该使用numpy进行矢量化:

In[11]:
df['F'] = np.sqrt(df['H']**2 +  df['Z']**2)
df

Out[11]: 
      H     D     Z             F
0  3235  6764  9546  10079.252998
1  1667  3455  7776   7952.676593
2  3555  3564  5433   6492.727778
3  2344  3333  8777   9084.605935
4  5666  3334  4444   7200.881335

关于您的错误,从DataFrame返回的可迭代是列:

for col in df:
    print(col)

H
D
Z
F

因此错误,迭代您使用的行iterrows

from math import sqrt
for x,y in df.iterrows():
    F=sqrt(y['H']**2+y['Z']**2)
    print(F)

10079.252998114493
7952.676593449529
6492.72777806062
9084.605935317173
7200.881334947827

但是对于简单的算术运算,你应该避免循环并寻找像numpy这样的矢量化解决方案,它会比循环更快,并且在数据大小增加时可以更好地扩展。

答案 1 :(得分:2)

在Pandas / Numpy / SciPy中,我们总是喜欢矢量化解决方案,因为它们更快,看起来更好,代码看起来更清晰,更短。

因此,请尝试使用numpy.linalg.norm()而不是循环:

In [34]: df['res'] = np.linalg.norm(df[['H','Z']], axis=1)

In [35]: df
Out[35]:
      H     D     Z           res
0  3235  6764  9546  10079.252998
1  1667  3455  7776   7952.676593
2  3555  3564  5433   6492.727778
3  2344  3333  8777   9084.605935
4  5666  3334  4444   7200.881335

答案 2 :(得分:2)

迭代DataFrame迭代列标签(如默认的dict迭代器迭代键)。要迭代行,您需要iterrows,或者更喜欢itertuples

尽管因为速度很慢,但仍然非常劝阻迭代。

此操作非常容易按列进行,因此不需要迭代

(df['H']**2 + df['Z']**2).pow(.5)