Yu *_*hen 7 python data-manipulation dataframe pandas
亲爱的熊猫专家:
我正在尝试实现一个函数来展平具有list类型元素的数据帧的列,我想要数据帧的每一行,其中列具有list类型的元素,所有列但是指定的列将被展平重复,而指定的列将具有列表中的值之一.
以下说明了我的要求:
input = DataFrame({'A': [1, 2], 'B': [['a', 'b'], 'c']})
A B
0 1 [a, b]
1 2 c
expected = DataFrame({'A': [1, 1, 2], 'B': ['a', 'b', 'c']}, index=[0, 0, 1])
A B
0 1 a
0 1 b
1 2 c
Run Code Online (Sandbox Code Playgroud)
我觉得可能有一个优雅的解决方案/概念,但我正在努力.
这是我的尝试,但尚未奏效.
def flattenColumn(df, column):
'''column is a string of the column's name.
for each value of the column's element (which might be a list), duplicate the rest of columns at the correspdonding row with the (each) value.
'''
def duplicate_if_needed(row):
return concat([concat([row.drop(column, axis = 1), DataFrame({column: each})], axis = 1) for each in row[column][0]])
return df.groupby(df.index).transform(duplicate_if_needed)
Run Code Online (Sandbox Code Playgroud)
在认识到alko的帮助下,这是我在数据帧中处理2个以上列的解决方案的简单概括:
def flattenColumn(input, column):
'''
column is a string of the column's name.
for each value of the column's element (which might be a list),
duplicate the rest of columns at the corresponding row with the (each) value.
'''
column_flat = pandas.DataFrame(
[
[i, c_flattened]
for i, y in input[column].apply(list).iteritems()
for c_flattened in y
],
columns=['I', column]
)
column_flat = column_flat.set_index('I')
return (
input.drop(column, 1)
.merge(column_flat, left_index=True, right_index=True)
)
Run Code Online (Sandbox Code Playgroud)
目前唯一的限制是列的顺序发生了变化,列展平将位于最右侧,而不是位于其原始位置.修复应该是可行的.
我想简单的方法来压缩列表列表将是一个纯python代码,因为这个对象类型不适合pandas或numpy.所以你可以用它来做
>>> b_flat = pd.DataFrame([[i, x]
... for i, y in input['B'].apply(list).iteritems()
... for x in y], columns=list('IB'))
>>> b_flat = b_flat.set_index('I')
Run Code Online (Sandbox Code Playgroud)
将B列展平后,您可以将其合并:
>>> input[['A']].merge(b_flat, left_index=True, right_index=True)
A B
0 1 a
0 1 b
1 2 c
[3 rows x 2 columns]
Run Code Online (Sandbox Code Playgroud)
如果希望重新创建索引(如预期结果),则可以添加.reset_index(drop=True)到上一个命令.
令人惊讶的是没有更“本地”的解决方案。将 @alko 的答案放入函数中非常简单:
def unnest(df, col, reset_index=False):
import pandas as pd
col_flat = pd.DataFrame([[i, x]
for i, y in df[col].apply(list).iteritems()
for x in y], columns=['I', col])
col_flat = col_flat.set_index('I')
df = df.drop(col, 1)
df = df.merge(col_flat, left_index=True, right_index=True)
if reset_index:
df = df.reset_index(drop=True)
return df
Run Code Online (Sandbox Code Playgroud)
然后简单地
input = pd.DataFrame({'A': [1, 2], 'B': [['a', 'b'], 'c']})
expected = unnest(input, 'B')
Run Code Online (Sandbox Code Playgroud)
我想最好允许一次取消嵌套多个列并处理名为 的嵌套列的可能性I,这会破坏此代码。
| 归档时间: |
|
| 查看次数: |
7427 次 |
| 最近记录: |