如果不重复生成列标题,如何将csv文件作为MultiIndexed DataFrame读入?

时间:2016-01-22 22:23:19

标签: python pandas

我想要读取多个.csv文件作为MultiIndexed DataFrames,但是不会重复生成列标题,因此我留下了两个标题而不是MultiIndex。

test.csv文件:

A,,B,,C,
a1,a2,b1,b2,c1,c2
1,1,1,1,1,1
2,2,2,2,2,2

当我运行以下内容时,

import pandas as pd

df = pd.read_csv('test.csv', header=[0,1])
print(df)

返回的结构不是我要找的东西:

   A Unnamed: 1_level_0  B Unnamed: 3_level_0  C Unnamed: 5_level_0
  a1                 a2 b1                 b2 c1                 c2
0  1                  1  1                  1  1                  1
1  2                  2  2                  2  2                  2

我想要一个MultiIndex,第一个列标题的行为如下:

   A     B     C 
  a1 a2 b1 b2 c1 c2
0  1  1  1  1  1  1
1  2  2  2  2  2  2

有没有办法按原样读取csv,以便获得所需的结构?如果没有,那么最有效的方法就是修改csv文件以便它们明确重复外部标题值,这样做是否最有效?

A,A,B,B,C,C
a1,a2,b1,b2,c1,c2
1,1,1,1,1,1
2,2,2,2,2,2

2 个答案:

答案 0 :(得分:0)

我不知道在单行中有任何方法可以做到这一点,但你可以在python中修复它,而不是手动编辑文件。

首先从Series的第一个level创建MultiIndex,确保按labels中给出的顺序排序值:

level_0 = pd.Series(df.columns.levels[0][df.columns.labels[0]])

然后将'Unnamed: *'值转换为None并执行fillna转发:

level_0[level_0.str.startswith('Unnamed: ')] = None
level_0 = level_0.fillna(method = 'ffill')

最后将系列valuesindex分配为levels的{​​{1}}和labels

DataFrame

答案 1 :(得分:0)

也许有点小技巧 - 首先read_csv没有标题multiindex,然后fillna第一行,从第一行和第二行创建新的import pandas as pd import io temp=u"""A,,B,,C, a1,a2,b1,b2,c1,c2 1,1,1,1,1,1 2,2,2,2,2,2""" #after testing replace io.StringIO(temp) to filename df = pd.read_csv(io.StringIO(temp), sep=",", index_col=None, header=None) print df # 0 1 2 3 4 5 #0 A NaN B NaN C NaN #1 a1 a2 b1 b2 c1 c2 #2 1 1 1 1 1 1 #3 2 2 2 2 2 2 df.ix[0,:] = df.ix[0,:].fillna(method='ffill') print df # 0 1 2 3 4 5 #0 A A B B C C #1 a1 a2 b1 b2 c1 c2 #2 1 1 1 1 1 1 #3 2 2 2 2 2 2 print zip(df.ix[0,:], df.ix[1,:]) #[('A', 'a1'), ('A', 'a2'), ('B', 'b1'), ('B', 'b2'), ('C', 'c1'), ('C', 'c2')] df.columns = pd.MultiIndex.from_tuples(zip(df.ix[0,:], df.ix[1,:])) df = df.ix[2:].reset_index(drop=True) print df # A B C # a1 a2 b1 b2 c1 c2 #0 1 1 1 1 1 1 #1 2 2 2 2 2 2 ,删除这些行并持续{ {3}}:

from selenium import webdriver
import time

# Credit


# Vars
website_name = input("Webstie: ")
class_name = input("Class name: ")
button_xpath = input("what's the XPATH that you want to click (normally a button): ")
number_of_pages = int(input("How many pages would you like to scrape: "))

path = r"C:\Users\Skid\Desktop\chromedriver.exe"
driver = webdriver.Chrome(path)
driver.get(website_name + "")


def NormalScrape():
    for x in range(number_of_pages):
        time.sleep(5)
    print("1")
    posts = driver.find_elements_by_class_name(class_name)
    time.sleep(2)
    print("2")
    driver.find_element_by_xpath('.' + button_xpath).click()
    for post in posts:
        print(post.text)

NormalScrape()