从列表中提取标题并创建一个带有标题并与列表元素并排的DataFrame

时间:2018-06-09 20:17:05

标签: python list pandas dataframe

在抓取网站后,我最终得到了一个如下所示的列表:

data = ['\xa0header1', 'element1', 'element2', 'element3', '\xa0header2', 'element4', 'element5']

等等。

我想用我抓取的数据创建一个熊猫数据框,如下所示:

          A         B
   0  element1   header1
   1  element2   header1
   2  element3   header1
   3  element4   header2
   4  element5   header2

所以,基本上,我想在下一列中显示在初始列表的一组元素上方的标题。

如果可以做到这一点,考虑到标题前面的特殊字符,可以很容易地在列表中查找它们?

2 个答案:

答案 0 :(得分:2)

itertools groupby + repeat + chain

这是使用itertools模块的一种解决方案。实质上,这些是我们需要进行的唯一操作:

  1. 分组项目是否以\xa0开头。
  2. 在分组后为列表列表中的每个列表重复标题。
  3. 系列AB
  4. 结果可删除嵌套列表。
  5. 至关重要的是,这些操作已经在标准库中懒得有效地实现,因此不需要在纯Python中重现(尽管这本身就是一个很好的学习练习)。

    完整的解决方案:

    from itertools import chain, groupby, repeat
    
    chainer = chain.from_iterable
    
    data = ['\xa0header1', 'element1', 'element2', 'element3',
            '\xa0header2', 'element4', 'element5']
    
    def condition(x):
        return x.startswith('\xa0')
    
    # create list of lists for elements
    elements = [list(j) for i, j in groupby(data, key=condition) if not i]
    
    # create list of headers
    headers = [next(j) for i, j in groupby(data, key=condition) if i]
    
    # chain list of lists, and use repeat for headers
    df = pd.DataFrame({'A': list(chainer(LoL)),
                       'B': list(chainer(repeat(i, j) for i, j in \
                                 zip(headers, map(len, elements))))})
    
    print(df)
    
              A         B
    0  element1   header1
    1  element2   header1
    2  element3   header1
    3  element4   header2
    4  element5   header2
    

答案 1 :(得分:0)

另一种解决方案是使用collections.defaultdict创建一个字典映射头到元素。可能比itertools.groupby更直观,只需要一次传递。

from collections import defaultdict
from itertools import chain, repeat

chainer = chain.from_iterable

data = ['\xa0header1', 'element1', 'element2', 'element3',
        '\xa0header2', 'element4', 'element5']

# create dictionary of lists
# each key a separate header; values are list of elements
d = defaultdict(list)

for item in data:
    if item.startswith('\xa0'):
        key = item.strip()
    else:
        d[key].append(item)

# chain list of lists, and use repeat for headers
df = pd.DataFrame({'A': list(chainer(d.values())),
                   'B': list(chainer(repeat(i, j) for i, j in \
                             zip(d.keys(), map(len, d.values()))))})

print(df)

          A        B
0  element1  header1
1  element2  header1
2  element3  header1
3  element4  header2
4  element5  header2