使用pandas将deg-min-sec转换为十进制度而不显式迭代

时间:2014-12-11 04:20:53

标签: python pandas

我正在使用pandas来获取这样的数据帧:

print (a) 

    0   1   2  3  4   5   6  7
0  36  30  36  N  2  31  18  W
1  36  43  52  N  2  17  25  W 
2  36  43  13  N  2  16  27  W
3  36  29  57  N  2  30  21  W
4  36  29  18  N  2  29  24  W

然后我尝试使用列0,1和2来获取纬度的值。但我需要在第3栏中基于半球的标志。

所需的输出将是这样的:

0    36.510000
1    36.731111
2    36.720278
3    36.499167
4    36.488333
5    36.709722
6    36.698889
7    36.477778
8    36.466944
9    36.688056

当我使用半球来获取坐标的符号时:

gg = a[0]+(a[1]+a[2]/60)/60 * -1 if a[3]=='S' else 1

引发了跟随者错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

如何使用另一列中的字符串转换完整列而不显式迭代数据框?

1 个答案:

答案 0 :(得分:1)

我冒昧地给你的数据框一些有意义的名字。

您需要apply每行的逻辑,如下所示:

# generate, load data
datastring = StringIO("""\
latD latM  latS latH lonD lonM lonS lonH
36  30  36  N  2  31  18  W
36  43  52  N  2  17  25  W 
36  43  13  N  2  16  27  W
36  29  57  N  2  30  21  W
36  29  18  N  2  29  24  W
""")
df = pandas.read_table(datastring, sep='\s+')

# define function to convert to decimalDegrees
def decimalDegree(degree, minute, second, hemisphere):
    if hemisphere.lower() in ["w", "s", "west", "south"]:
        factor = -1.0
    elif hemisphere.lower() in ["n", "e", "north", "east"]:
        factor = 1.0
    else:
        raise ValueError("invalid hemisphere")

    # check the order of operations in your code
    return factor * (degree + (minute + second/60.)/60.)

# apply that function along to rows, using lambda
# to specify the columns to use as input
df['latitude'] = df.apply(
    lambda row: decimalDegree(row['latD'], row['latM'], row['latS'], row['latH']),
    axis=1
)

df['longitude'] = df.apply(
    lambda row: decimalDegree(row['lonD'], row['lonM'], row['lonS'], row['lonH']),
    axis=1
)

print(df)

那就给我:

   latD  latM  latS latH  lonD  lonM  lonS lonH   latitude  longitude
0    36    30    36    N     2    31    18    W  36.510000  -2.521667
1    36    43    52    N     2    17    25    W  36.731111  -2.290278
2    36    43    13    N     2    16    27    W  36.720278  -2.274167
3    36    29    57    N     2    30    21    W  36.499167  -2.505833
4    36    29    18    N     2    29    24    W  36.488333  -2.490000