使用 pd.read_clipboard 复制 MultiIndex 数据帧?

Posted

技术标签:

【中文标题】使用 pd.read_clipboard 复制 MultiIndex 数据帧?【英文标题】:Copying MultiIndex dataframes with pd.read_clipboard? 【发布时间】:2018-01-26 04:32:27 【问题描述】:

给定一个dataframe like this:

          C
A   B      
1.1 111  20
    222  31
3.3 222  24
    333  65
5.5 333  22
6.6 777  74 

如何使用pd.read_clipboard 阅读它?我试过这个:

df = pd.read_clipboard(index_col=[0, 1])

但是它会抛出一个错误:

ParserError: Error tokenizing data. C error: Expected 2 fields in line 3, saw 3

我该如何解决这个问题?

【问题讨论】:

哈哈哈哈哈哈哈哈哈哈......说真的,我希望你能。随意编写解析器并为 pandas 项目做出贡献。如果您这样做,我将不胜感激(-: 哇...真的吗? :( 像 Scott 一样,我总是将列向下移动,然后手动设置索引。我以为我是唯一一个做多余的事情的人……嗯。 我想我比较懒惰,有时看到多索引 df 时我只是避免回答问题:) @Wen 当然!将开始一个系列:) @MSeifert 当然,很抱歉。添加了链接。作为参考,这里也是:***.com/questions/17921010/… 【参考方案1】:

更新:现在它解析剪贴板 - 即无需事先保存

def read_clipboard_mi(index_names_row=None, **kwargs):
    encoding = kwargs.pop('encoding', 'utf-8')

    # only utf-8 is valid for passed value because that's what clipboard
    # supports
    if encoding is not None and encoding.lower().replace('-', '') != 'utf8':
        raise NotImplementedError(
            'reading from clipboard only supports utf-8 encoding')

    from pandas import compat, read_fwf
    from pandas.io.clipboard import clipboard_get
    from pandas.io.common import StringIO
    data = clipboard_get()

    # try to decode (if needed on PY3)
    # Strange. linux py33 doesn't complain, win py33 does
    if compat.PY3:
        try:
            text = compat.bytes_to_str(
                text, encoding=(kwargs.get('encoding') or
                                get_option('display.encoding'))
            )
        except:
            pass

    index_names = None
    if index_names_row:
        if isinstance(index_names_row, int):
            index_names = data.splitlines()[index_names_row].split()
            skiprows = [index_names_row]
            kwargs.update('skiprows': skiprows)
        else:
            raise Exception('[index_names_row] must be of [int] data type')

    df = read_fwf(StringIO(data), **kwargs)
    unnamed_cols = df.columns[df.columns.str.contains(r'Unnamed:')].tolist()

    if index_names:
        idx_cols = df.columns[range(len(index_names))].tolist()
    elif unnamed_cols:
        idx_cols = df.columns[range(len(unnamed_cols))].tolist()
        index_names = [None] * len(idx_cols)

    df[idx_cols] = df[idx_cols].ffill()
    df = df.set_index(idx_cols).rename_axis(index_names)

    return df

在没有索引名称的情况下测试多索引 DF:

In [231]: read_clipboard_mi()
Out[231]:
          C
1.1 111  20
    222  31
3.3 222  24
    333  65
5.5 333  22
6.6 777  74

使用索引名称测试多索引 DF:

In [232]: read_clipboard_mi(index_names_row=1)
Out[232]:
          C
A   B
1.1 111  20
    222  31
3.3 222  24
    333  65
5.5 333  22
6.6 777  74

注意:

    没有经过很好的测试 不支持多级列 见第 1 点 ;-)

注意2:请随意使用此代码或创建a pull request on Pandas github

【讨论】:

哇,看起来棒极了!您应该考虑向 pandas 开发人员提交 PR。 不错,期待 pandas 作为新功能添加~ :) 谢谢你们!我认为我没有足够的时间和耐心来编写所有必要的测试...... 将使用该函数代替read_clipboard,并尝试对其进行测试甚至添加更多功能 是的,我会为此奖励一笔奖金。你想要多少? 50? 100? 200?这个答案当然值得。

以上是关于使用 pd.read_clipboard 复制 MultiIndex 数据帧?的主要内容,如果未能解决你的问题,请参考以下文章

使用 pd.read_clipboard 指定多级列?

使用 pd.read_clipboard 时如何处理包含空格的列名?

来自云托管的 jupyter 的 pandas.read_clipboard?

读取剪贴板在 jupyter 或终端中不起作用

pandas-20 DataFrame()的基本操作

如何从 matplotlib 中的数据框列生成 x 轴值?