将csv行中的文本分隔成多个?

时间:2018-07-24 19:24:44

标签: python python-3.x csv

我有一个.csv文件,其行:NAMELOCATIONIP AddressIP Address行中有许多IP,它们之间用空格分隔,最多5个字符。例如:

编辑:

Name,Location,IP Address
Router,China,10.10.10.1     10.10.10.2     10.10.10.3     10.10.10.4     10.10.10.5
Switch,USA,192.168.1.1     192.168.1.2     192.168.1.3

以此类推。

我希望所有IP都位于IP Address列下的单独行中。这就是我希望输出看起来像的样子:

Name,Location,IP Address
Router,China,10.10.10.1
Router,China,10.10.10.2
Router,China,10.10.10.3
Router,China,10.10.10.4
Router,China,10.10.10.5
Switch,USA,192.168.1.1
Switch,USA,192.168.1.2
Switch,USA,192.168.1.3

我一直在尝试做.split(),但这给我一个错误。谁能帮我吗?

使用csv.DictReader在此处读取我的csv文件。

2 个答案:

答案 0 :(得分:1)

基本思想是将IP地址字符串及其空格分隔为一个包含IP地址列表/数组的列表。然后将其分解为长格式,而每个组合(值)都表示为单行。我一步一步地利用了熊猫DataFrame及其groupby函数,然后是自定义apply函数。对于您的问题,此代码有效:

import pandas as pd

columns = ['Name', 'Location', 'IP Address']

data = [
    ['Router', 'China', '10.10.10.1    10.10.10.2     10.10.10.3'],
    ['Switch', 'USA', '192.168.1.1   192.168.1.2     192.168.1.3']
]

#df = pd.read_csv(your_file_name)
df = pd.DataFrame(data, columns=columns)

def extract_ip_addresses(df_group):
    row = df_group.iloc[0]
    name = row['Name']
    location = row['Location']
    grouped_data = [[name, location, ip] for ip in row['IP Address'].split()]
    return pd.DataFrame(grouped_data, columns=columns)

df.groupby(['Name', 'Location'], group_keys=False).apply(extract_ip_addresses).reset_index(drop=True)

这将产生以下结果:

    Name    Location    IP Address
0   Router  China   10.10.10.1
1   Router  China   10.10.10.2
2   Router  China   10.10.10.3
3   Switch  USA     192.168.1.1
4   Switch  USA     192.168.1.2
5   Switch  USA     192.168.1.3

对于您而言,您可以通过pd.read_csv(your_file_name)读取初始数据。

以下是一些详细的示例:

有关更多详细信息,请参阅Pandas documentation

答案 1 :(得分:0)

我假设这些字段确实由逗号分隔,没有空格填充,并且IP地址由多个空格分隔。然后这将起作用:

RE_SEPARATOR = re.compile(' +')
with open(path) as f:
    for row in csv.DictReader(f):
        addresses = RE_SEPARATOR.split(row["IP Address"])
        for address in addresses:
            print(row["Name"], row["Location"], address)

您将需要调整print函数调用,以便它提供您需要的输出格式(根据您的描述,这并不是很清楚)。

如果要删除重复的地址,请改用此地址:

        addresses = set(RE_SEPARATOR.split(row["IP Address"]))

这不会保留保留顺序。在Python 3.7(以及在3.6中也是非正式的)中,您可以使用dict保留顺序:

        addresses = dict.fromkeys(RE_SEPARATOR.split(row["IP Address"]))