pandas数据处理:合并数据框中相同的行,多行信息结合输出为一条

熟悉Linux系统命令的都知道,last命令查看有哪些ip登录了本机:

pandas数据处理:合并数据框中相同的行,多行信息结合输出为一条_第1张图片

现在将last -F 后输出的内容加以处理,得到以下txt文件:

pandas数据处理:合并数据框中相同的行,多行信息结合输出为一条_第2张图片

现在的需求是:

判断本地IP的服务器是否重启过(reboot),重启过即为异常,否则为正常;是否为终端(tty*)登录,如果是为异常,否则为正常(pts/*)。

输出要求(例):

pandas数据处理:合并数据框中相同的行,多行信息结合输出为一条_第3张图片

第一步:将数据转换为数据框

import pandas as pd

 #路径为你文件的位置,以项目名称为根开始
dataframe = pd.read_csv(r"../../last_20200913_10.10.11.107.log", header=None, delimiter='|')  
dataframe.columns=['本地IP','用户名', '终端位置', '登录ip', '开始日期', '开始时间', '结束日期', '结束时间', '持续时间']
print(dataframe)

pandas数据处理:合并数据框中相同的行,多行信息结合输出为一条_第4张图片

第二步:按需求开始做判断

 # 1.如果用户名这一列含有reboot或者终端位置为含有tty则返回这一行
 # 2.如果用户名含有root并且终端含有tty则返回这一行
 # 将2.追加到1.后面
df=last_df[last_df['用户名'].isin(['reboot']) | last_df['终端位置'].str.contains('tty') ]\
            .append(last_df[last_df['用户名'].isin(['root']) & last_df['终端位置'].str.contains('pts')].drop_duplicates(['本地IP'])).reset_index(drop=True)

print(df)

pandas数据处理:合并数据框中相同的行,多行信息结合输出为一条_第5张图片

第三步:按目标格式输出

word_df = pd.DataFrame(columns=['服务器IP地址', '服务器重启', '本地连接', '详细信息'])
word_df['服务器IP地址']=df['本地IP']
word_df['服务器重启']=df.用户名.apply(lambda x: '异常' if 'reboot' in x else '正常')
word_df['本地连接']=df.终端位置.apply(lambda x: '异常' if 'tty' in x else '正常')
word_df['详细信息']='查看'
print(word_df)

pandas数据处理:合并数据框中相同的行,多行信息结合输出为一条_第6张图片

现在有个问题,我们只需要一个IP,只要用户名中含有一个reboot就算服务器重启过,有异常;终端位置也是,只要有tty就算是有异常了。

但是现在的数据框有相同的 服务器IP地址,怎么处理才能使其变成一条呢。

我想了一个办法:利用groupby方法,将df数据框,以 本地IP  分组,将用户名和终端位置 连接到一行,然后再进行判断是否为异常。

    #以本地IP分组,将用户名和终端位置 连接到一行
    user_df=df.groupby(['本地IP'])['用户名'].apply(lambda x:','.join(x.values)).to_frame().reset_index()
    local_df = df.groupby(['本地IP'])['终端位置'].apply(lambda x:','.join(x.values)).to_frame().reset_index(drop=True)
    total_df=user_df.join(local_df)
    # print('2222',user_df)
    # print(local_df)
    # print(total_df)
    
    word_df = pd.DataFrame(columns=['服务器IP地址', '服务器重启', '本地连接', '详细信息'])
    word_df['服务器IP地址']=total_df['本地IP']
    word_df['服务器重启']=total_df.用户名.apply(lambda x: '异常' if 'reboot' in x else '正常')
    word_df['本地连接']=total_df.终端位置.apply(lambda x: '异常' if 'tty' in x else '正常')
    word_df['详细信息']='查看'

    print(word_df)

pandas数据处理:合并数据框中相同的行,多行信息结合输出为一条_第7张图片

这样就得到我们想要的结果了。

完整的实现代码:

import pandas as pd


#读文件,以| 为分隔
dataframe = pd.read_csv(r"../../last_20200913_10.10.11.107.log", header=None, delimiter='|')
dataframe.columns=['本地IP','用户名', '终端位置', '登录ip', '开始日期', '开始时间', '结束日期', '结束时间', '持续时间']
#print(dataframe)


def linux_login(last_df):
    '''

    :param last_df:
    :return:
    '''

    # 1.如果用户名这一列含有reboot或者终端位置为含有tty则返回这一行
    # 2.如果用户名含有root并且终端含有tty则返回这一行
    # 将2.追加到1.后面
    df=last_df[last_df['用户名'].isin(['reboot']) | last_df['终端位置'].str.contains('tty') ]\
            .append(last_df[last_df['用户名'].isin(['root']) & last_df['终端位置'].str.contains('pts')].drop_duplicates(['本地IP'])).reset_index(drop=True)
    
    
    #以本地IP分组,将用户名和终端位置 连接到一行
    user_df=df.groupby(['本地IP'])['用户名'].apply(lambda x:','.join(x.values)).to_frame().reset_index()
    local_df = df.groupby(['本地IP'])['终端位置'].apply(lambda x:','.join(x.values)).to_frame().reset_index(drop=True)
    total_df=user_df.join(local_df)
    # print('2222',user_df)
    # print(local_df)
    # print(total_df)
    
    word_df = pd.DataFrame(columns=['服务器IP地址', '服务器重启', '本地连接', '详细信息'])
    word_df['服务器IP地址']=total_df['本地IP']
    word_df['服务器重启']=total_df.用户名.apply(lambda x: '异常' if 'reboot' in x else '正常')
    word_df['本地连接']=total_df.终端位置.apply(lambda x: '异常' if 'tty' in x else '正常')
    word_df['详细信息']='查看'

    print(word_df)
    # return word_df

linux_login(dataframe)

 

你可能感兴趣的:(python,自动化运维,Linux运维,python,pandas,数据处理)