如何从熊猫核心系列中获得价值?

时间:2019-06-12 18:12:50

标签: python pandas dataframe

我有一个数据帧df,其中是特定IP地址的时区:

ip1         ip2           timezone
0           16777215          0
16777216    16777471       +10:00
16777472    16778239       +08:00
16778240    16779263       +11:00
16779264    16781311       +08:00
16781312    16785407       +09:00
...

第一行对从0到16777215的IP地址有效,第二行从16777216到16777471等等。 现在,我经过一个文件夹,想知道每个文件的时区(在计算文件的ip_number之后)。 我使用:

time=df.loc[(df['ip1'] <= ip_number) & (ip_number <= df['ip2']), 'timezone']

并成为我的预期输出:

1192    +05:30
Name: timezone, dtype: object

但这是熊猫系列的核心系列,我只想拥有“ +5:30”。 我怎么变成这个?还是有其他方法可以代替df.loc[...]直接成为timezonedf列的值?

2 个答案:

答案 0 :(得分:0)

要从大小为1的系列中提取唯一值,请使用Series.item() method

time = df.loc[(df['ip1'] <= ip_number) & (ip_number <= df['ip2']), 'timezone'].item()

请注意,如果系列包含多个项目,则会产生ValueError


通常从系列中提取单个值是一种反模式。 NumPy /熊猫 围绕将向量化函数应用于大型数组的想法是 比使用处理单个Python循环的速度要快得多 一次值一个。

给出您的df和IP地址列表,这是一种查找 只需一次致电pd.merge_asof所有 IP号码的相应时区偏移。

import pandas as pd
df = pd.DataFrame({'ip1': [0, 16777216, 16777472, 16778240, 16779264, 16781312],
                   'ip2': [16777215, 16777471, 16778239, 16779263, 16781311, 16785407],
                   'timezone': ['0', '+10:00', '+08:00', '+11:00', '+08:00', '+09:00']})

df1 = df.melt(id_vars=['timezone'], value_name='ip').sort_values(by='ip').drop('variable', axis=1)
ip_nums = [16777473, 16777471, 16778238, 16785406]
df2 = pd.DataFrame({'ip':ip_nums}).sort_values(by='ip')
result = pd.merge_asof(df2, df1)
print(result)

收益

         ip timezone
0  16777471   +10:00
1  16777473   +08:00
2  16778238   +08:00
3  16785406   +09:00

理想情况下,下一步是应用更多NumPy / Pandas向量化函数 一次处理整个DataFrame。但是,如果必须,您可以进行迭代 通过result DataFrame逐行访问。不过,您的代码看起来会更干净 因为您将能够轻松读取ip和相应的偏移量(而无需调用.item())。

for row in result.itertuples():
    print('{} --> {}'.format(row.ip, row.timezone))
# 16777471 --> +10:00
# 16777473 --> +08:00
# 16778238 --> +08:00
# 16785406 --> +09:00

答案 1 :(得分:0)

只列出它

list(time)

如果仅排除一个值

list(time)[0]

或者您可以更早实现:

#for numpy array
time=df.loc[(df['ip1'] <= ip_number) & (ip_number <= df['ip2']), 'timezone'].values

#for list
time=list(df.loc[(df['ip1'] <= ip_number) & (ip_number <= df['ip2']), 'timezone'].values)