pandas,如何将列添加到多索引列DataFrame

时间:2016-01-27 03:00:12

标签: python pandas

这是我原来的DataFrame(带有多索引列):

In [72]:df
Out[72]: 
          a                   b          
          x         y         x         y
0  1.545293 -0.459270  0.899254 -1.010453
1  0.458760  0.275400 -0.190951  0.169195
2 -0.941817  1.109823  0.077953 -0.247074
3  1.790101 -1.643470  0.979625 -1.704657
4 -2.044814 -0.243726 -0.039724  0.600066

我有另一个DataFrame:

In [77]:df2
Out[77]: 
          x         y
0 -1.085869 -0.952949
1  0.601585  0.570050
2  0.328601  0.802610
3 -0.415952 -0.090088
4  0.757545 -0.736933

如何将df2的列添加到df以获取这样的新DataFrame:

In [83]:df3
Out[83]: 
          a                   b                   c          
          x         y         x         y         x         y
0  1.545293 -0.459270  0.899254 -1.010453 -1.085869 -0.952949
1  0.458760  0.275400 -0.190951  0.169195  0.601585  0.570050
2 -0.941817  1.109823  0.077953 -0.247074  0.328601  0.802610
3  1.790101 -1.643470  0.979625 -1.704657 -0.415952 -0.090088
4 -2.044814 -0.243726 -0.039724  0.600066  0.757545 -0.736933

我目前的方法是使用for循环:

for col in df2.columns:
    df['c', col] = df2[col]

有什么方法可以避免循环吗?

3 个答案:

答案 0 :(得分:1)

尝试pd.concat

pieces = {'a' : df1['a'],
          'b' : df1['b'],
          'c' : df2}
df3 = pd.concat(pieces, axis=1)

答案 1 :(得分:0)

我在一般情况(运行Python 3.6)中发现了另一种方法,而不必明确解构DataFrame。您可以将pd.concat与字典参数

一起使用
df3 = pd.concat({**df1, **{('c',nm):val for nm,val in df2.items()})
**个对象的

DataFrame扩展似乎会返回系列对象的字典,其中包含"名称"等于列名字符串/值,或者如果列是 MultiIndexed ,则包含列字符串/值的hieararchy的元组。然后,当作为字典读回pd.concat时,Pandas从元组重新构造MultiIndexed列。

请注意,这比您正在进行的直接分配效率低得多!由于它必须解构数据帧的每个列和MultiIndex,然后重新组合。

答案 2 :(得分:0)

我认为堆叠是这里最好的解决方案:

function DataTable({columns, data_rows}) {
    const [data, changeData] = useState(data_rows);

    if (columns[0].Header !== "Action") {
        columns.unshift({
            Header: 'Action'
        });
    }
    columns[0]['columns'] = [{
        Header: ' ', Cell: ({row}) => (
            <ButtonGroup>
                <Button className="button-dark button-sm" onClick={() => {
                    const dataCopy = [...data];
                    dataCopy.splice(row.index, 1);
                    changeData(dataCopy);}}>
                    Remove
                </Button>
            </ButtonGroup>
        )
    }]
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow
    } = useTable({
        columns,
        data
    });


    return (
        <table {...getTableProps()}>
            <thead>
            {headerGroups.map(headerGroup => (
                <tr {...headerGroup.getHeaderGroupProps()}>
                    {headerGroup.headers.map(column => (
                        <th {...column.getHeaderProps()}>{column.render("Header")}</th>
                    ))}
                </tr>
            ))}
            </thead>
            <tbody {...getTableBodyProps()}>
            {rows.map((row, i) => {
                prepareRow(row);
                return (
                    <tr {...row.getRowProps()}>
                        {row.cells.map(cell => {
                            return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
                        })}
                    </tr>
                );
            })}
            </tbody>
        </table>
    );
}