如何删除和移动 pandas df 列中的值
How to delete and shift values in a pandas df column
我有一个 pandas df
想要操作,因此已订购。所以对于下面的df
,我想订购['I']
。因此值将显示为 10-50。我有 2 个选项可以做到这一点;
1) 尝试删除列 ['G']
或 ['H']
中的值。因此,如果值为 == X
,则删除。
2) 当 == X
时尝试合并相同列中的值
import pandas as pd
d = pd.DataFrame({
'J' : [10,'B','C','C',50],
'I' : ['B',20,30,40,'C'],
'H' : ['X','A','C','B','X'],
'G' : ['X', 'B', 'A','B','X'],
})
输出:
G H I J
0 X X B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X X C 50
选项 1 是我们从 Column H
中删除 X
,预期输出为:
G H I J
0 X B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X C 50
选项 2 是我们在 Column G-H
中合并 X
并且预期输出将是:
G H I J
0 XX B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 XX C 50
我玩过 df = df.drop(df.H == 'X')
但这会删除整行。
选项 1:
对于满足条件 df.H == 'X'
:
的行,您可以将值左移
具有以下变量定义:
hij = ['H', 'I', 'J']
x = df.H=='X'
我们可以简明扼要地写出班次分配。
df.loc[x, hij] = df.loc[x, hij].apply(lambda x: x.shift(-1), axis=1)
outputs:
G H I J
0 X B 10 NaN
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X C 50 NaN
选项 2:
原理相同,但需要两个语句。
我们可以将 H
连接到 G
df.loc[x, 'G'] = df.loc[x, 'G'] + df.loc[x, 'H']
# df.loc[x, 'G'] = df.loc[x, ['G, 'H']].sum(axis=1)
# or df.loc[x, ['G', 'H']].apply(np.sum, axis=1)
# or df.loc[x, 'G'] = df.loc[x, ['G', 'H']].apply(lambda x: (x + x.shift(-1))[0], axis=1)
并像选项 1 那样移动
df.loc[x, hij] = df.loc[x, hij].apply(lambda x: x.shift(-1), axis=1)
final output:
G H I J
0 XX B 10 NaN
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 XX C 50 NaN
更通用的解决方案应该是更改条件,如果 G
或 H
列是 X
,然后合并在一起并 shift
按条件:
d = pd.DataFrame({
'J' : [10,'B','C','C',50, 60],
'I' : ['B',20,30,40,'C', 'D'],
'H' : ['X','A','C','B','X', 'Y'],
'G' : ['Y', 'B', 'A','B','X', 'X'],
}, columns=list('GHIJ'))
print (d)
G H I J
0 Y X B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X X C 50
5 X Y D 60
m = d[['G','H']].eq('X').any(axis=1)
print (m)
0 True
1 False
2 False
3 False
4 True
5 True
dtype: bool
d['H'] = d['G'] + d['H']
d[m] = d[m].shift(-1, axis=1)
print (d)
G H I J
0 YX B 10 NaN
1 B BA 20 B
2 A AC 30 C
3 B BB 40 C
4 XX C 50 NaN
5 XY D 60 NaN
对于你的问题一,将 'X' 替换为 np.nan ,然后对数据框进行排序(移动值)
d.replace({'H':{'X':np.nan}}).apply(lambda x: sorted(x, key=pd.isnull),1).fillna('')
Out[234]:
G H I J
0 X B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X C 50
问题二:先用np.where创建d.G,然后同上
d.G=np.where((d.G=='X')&(d.H=='X'),'XX',d.G)
d.replace({'H':{'X':np.nan}}).apply(lambda x: sorted(x, key=pd.isnull),1).fillna('')
Out[242]:
G H I J
0 XX B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 XX C 50
您可以选择 np.where
和 shift
即
ndf = pd.DataFrame(np.where((d['H']=='X')[:,None],
d.assign(H=d.H+d.G).shift(-1,axis=1), #only d.shift(...) in case you dont want to add
d), columns=d.columns)
G H I J
0 XX B 10 NaN
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 XX C 50 NaN
我有一个 pandas df
想要操作,因此已订购。所以对于下面的df
,我想订购['I']
。因此值将显示为 10-50。我有 2 个选项可以做到这一点;
1) 尝试删除列 ['G']
或 ['H']
中的值。因此,如果值为 == X
,则删除。
2) 当 == X
import pandas as pd
d = pd.DataFrame({
'J' : [10,'B','C','C',50],
'I' : ['B',20,30,40,'C'],
'H' : ['X','A','C','B','X'],
'G' : ['X', 'B', 'A','B','X'],
})
输出:
G H I J
0 X X B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X X C 50
选项 1 是我们从 Column H
中删除 X
,预期输出为:
G H I J
0 X B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X C 50
选项 2 是我们在 Column G-H
中合并 X
并且预期输出将是:
G H I J
0 XX B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 XX C 50
我玩过 df = df.drop(df.H == 'X')
但这会删除整行。
选项 1:
对于满足条件 df.H == 'X'
:
具有以下变量定义:
hij = ['H', 'I', 'J']
x = df.H=='X'
我们可以简明扼要地写出班次分配。
df.loc[x, hij] = df.loc[x, hij].apply(lambda x: x.shift(-1), axis=1)
outputs:
G H I J
0 X B 10 NaN
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X C 50 NaN
选项 2:
原理相同,但需要两个语句。
我们可以将 H
连接到 G
df.loc[x, 'G'] = df.loc[x, 'G'] + df.loc[x, 'H']
# df.loc[x, 'G'] = df.loc[x, ['G, 'H']].sum(axis=1)
# or df.loc[x, ['G', 'H']].apply(np.sum, axis=1)
# or df.loc[x, 'G'] = df.loc[x, ['G', 'H']].apply(lambda x: (x + x.shift(-1))[0], axis=1)
并像选项 1 那样移动
df.loc[x, hij] = df.loc[x, hij].apply(lambda x: x.shift(-1), axis=1)
final output:
G H I J
0 XX B 10 NaN
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 XX C 50 NaN
更通用的解决方案应该是更改条件,如果 G
或 H
列是 X
,然后合并在一起并 shift
按条件:
d = pd.DataFrame({
'J' : [10,'B','C','C',50, 60],
'I' : ['B',20,30,40,'C', 'D'],
'H' : ['X','A','C','B','X', 'Y'],
'G' : ['Y', 'B', 'A','B','X', 'X'],
}, columns=list('GHIJ'))
print (d)
G H I J
0 Y X B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X X C 50
5 X Y D 60
m = d[['G','H']].eq('X').any(axis=1)
print (m)
0 True
1 False
2 False
3 False
4 True
5 True
dtype: bool
d['H'] = d['G'] + d['H']
d[m] = d[m].shift(-1, axis=1)
print (d)
G H I J
0 YX B 10 NaN
1 B BA 20 B
2 A AC 30 C
3 B BB 40 C
4 XX C 50 NaN
5 XY D 60 NaN
对于你的问题一,将 'X' 替换为 np.nan ,然后对数据框进行排序(移动值)
d.replace({'H':{'X':np.nan}}).apply(lambda x: sorted(x, key=pd.isnull),1).fillna('')
Out[234]:
G H I J
0 X B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 X C 50
问题二:先用np.where创建d.G,然后同上
d.G=np.where((d.G=='X')&(d.H=='X'),'XX',d.G)
d.replace({'H':{'X':np.nan}}).apply(lambda x: sorted(x, key=pd.isnull),1).fillna('')
Out[242]:
G H I J
0 XX B 10
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 XX C 50
您可以选择 np.where
和 shift
即
ndf = pd.DataFrame(np.where((d['H']=='X')[:,None],
d.assign(H=d.H+d.G).shift(-1,axis=1), #only d.shift(...) in case you dont want to add
d), columns=d.columns)
G H I J
0 XX B 10 NaN
1 B A 20 B
2 A C 30 C
3 B B 40 C
4 XX C 50 NaN