我有一个数据帧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[...]
直接成为timezone
中df
列的值?
答案 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)