【问题标题】:Detemining Odd and Even values with Pandas in Python在 Python 中使用 Pandas 确定奇数和偶数
【发布时间】:2020-12-15 12:39:29
【问题描述】:

我有以下一些 IP 地址,我想根据它们的最后一位数字对其进行分类。

一个 IPv4 地址由四个数字组成:

  • 每个都包含一到三位数字(0-255)
  • 用一个点 (.) 分隔每个数字或一组数字

现在我想引用 IP 地址的最后一位数字,如果它是 [Odd],则相关列用 Odd 完成,如果它是 [Even],它将用偶数完成。

IP Address          
192.168.1.1         #last digit is 1 and consider it as odd
192.168.1.2         #last digit is 2 and even
192.168.152.200     #last digit is 200 and is even
192.168.54.98       #last digit is 98 and is even
192.168.98.93       #last digit is 93 and is odd
 .....
 ......

预期结果:

IP Address                 Status
192.168.1.1                Odd
192.168.1.2                Even
192.168.152.200            Even
192.168.54.98              Even
192.168.98.93              Odd
........ 
........

【问题讨论】:

  • 取最后一个数,然后使用取模运算。如果n % 2 is 0,则为偶数。
  • 我是 pandas 和正则表达式的新手,介意请与我分享代码。
  • 我相信这与正则表达式无关。我觉得你可以通过taking the last part of a string 并使用基本算术来做到这一点。

标签: python pandas python-2.7 dataframe


【解决方案1】:

数据:

df = pd.DataFrame({"IP Address" : 
["192.168.1.1",
"192.168.1.2",
"192.168.152.200",
"192.168.54.98",
"192.168.98.93"]})

df:

        IP Address
0      192.168.1.1
1      192.168.1.2
2  192.168.152.200
3    192.168.54.98
4    192.168.98.93
df['New-variable'] = df['IP Address'].apply(lambda x:"Odd" if int(x.split(".")[-1]) % 2 else  "Even")

df:

        IP Address New-variable
0      192.168.1.1          Odd
1      192.168.1.2         Even
2  192.168.152.200         Even
3    192.168.54.98         Even
4    192.168.98.93          Odd

【讨论】:

    【解决方案2】:

    假设你的 df 被称为 x,你可以这样做:

    import numpy as np
    # First remove the '.' so that you can convert to float
    x['IP_num'] = (x['IP'].apply(lambda x: ''.join([ch for ch in x if ch.isdigit()]))).astype(float)
    # Then create a new column if the IP is odd / even
    x['even_odd'] = np.where(x['IP_num'] % 2 == 0,'Even','Odd')
    

    输出:

                    IP             IP_num even_odd
    0      192.168.1.1      19,216,811.00      Odd
    1      192.168.1.1      19,216,811.00      Odd
    2  192.168.152.200 192,168,152,200.00     Even
    3    192.168.54.98   1,921,685,498.00     Even
    4    192.168.98.93   1,921,689,893.00      Odd
    

    您可以根据需要删除“IP_num”列。

    【讨论】:

    • 太好了,我完全理解了。
    • 很高兴我能帮上忙。
    【解决方案3】:

    你可以试试这个

    IPList = ["192.168.1.1",
        "192.168.1.1" ,       
        "192.168.1.2",         
        "192.168.152.200",   
        "192.168.54.98",      
        "192.168.98.93" ]      
    final_list = []
    for ip in IPList:
        _ip = ip.split(".")
        if int(_ip[-1]) %2==0:
            final_list.append([ip,'Even'])
            continue
        final_list.append([ip,'Odd'])
    df = pd.DataFrame(final_list, columns =['IP Address', 'Type']) 
    df 
    

    输出:

        IP Address      Type
    0   192.168.1.1     Odd
    1   192.168.1.1     Odd
    2   192.168.1.2     Even
    3   192.168.152.200 Even
    4   192.168.54.98   Even
    5   192.168.98.93   Odd
    

    【讨论】:

      【解决方案4】:

      这里不需要forapply 循环 - 在最后一个. 之后提取值,转换为整数,使用% 2 并最后传递给numpy.where

      df['new'] = np.where(df['IP Address'].str.split('.').str[-1].astype(int) % 2,'Odd','Even')
          
      print (df)
              IP Address   new
      0      192.168.1.1   Odd
      1      192.168.1.2  Even
      2  192.168.152.200  Even
      3    192.168.54.98  Even
      4    192.168.98.93   Odd
      

      【讨论】:

        【解决方案5】:
        df
        

        df['Status'] = [int(str(x).strip()[-1]) for x in df['IP Address']]
        
        df['Status'] = np.where(df['Status']%2, 'Odd', 'Even')
        

        【讨论】:

          【解决方案6】:

          这只是显示输入:

          import pandas as pd
          
          adr_df = pd.DataFrame(['192.168.1.1', '192.168.1.2', '192.168.152.200', 
                                  '192.168.54.98', '192.168.98.93'], columns=['IP Adress'])
          

          举个例子,如果你真的喜欢使用 regex 来捕获最后一个数字,你可以使用以下命令(小心使用 \. 转义点字符):

          adr_df['Last Nr'] = adr_df['IP Adress'].str.extract(r'.*\..*\..*\.(.*)').astype(int)
          

          当然,可能有更精确的正则表达式字符串来匹配 ip,但这个对我有用。

          用一个小的 lambda 函数检查你可以达到的 odness:

          adr_df.loc['Status'] = adr_df['Last Nr'].apply(lambda x: 'Odd' if x%2 else 'Even')
          

          【讨论】:

            【解决方案7】:

            你可以extract最后一个数字,然后使用方法divmodmap

            df['IP Adress'].str.extract('(\d+)$', expand=False).astype(int)\
            .divmod(2)[1].map({1: 'odd', 0: 'even'})
            

            【讨论】:

              猜你喜欢
              • 2019-03-19
              • 1970-01-01
              • 2020-01-18
              • 1970-01-01
              • 2017-02-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-11
              相关资源
              最近更新 更多