100行和列),我想提取“几乎相同”的列,即具有> 2个共同值(在同一索引处),并且在其他索引处-6ren">
gpt4 book ai didi

python - 有没有办法获得 pandas DataFrame 的几列的 "union"?

转载 作者:行者123 更新时间:2023-12-01 03:07:39 26 4
gpt4 key购买 nike

我不是在寻找合并/连接列或用其他值替换某些值(尽管......也许是?)。但是我有一个很大的数据框(> 100行和列),我想提取“几乎相同”的列,即具有> 2个共同值(在同一索引处),并且在其他索引处没有不同的值(如果一列中有一个值,则另一列中必须有相同的值或 NaN)。这是此类数据框的示例:

a = np.random.randint(1,10,10)
b = np.array([np.nan,2,np.nan,3,np.nan,6,8,1,2,np.nan])
c = np.random.randint(1,10,10)
d = np.array([7,2,np.nan,np.nan,np.nan,6,8,np.nan,2,2])
e = np.array([np.nan,2,np.nan,np.nan,np.nan,6,8,np.nan,np.nan,2])
f = np.array([np.nan,2,np.nan,3.0,7,np.nan,8,np.nan,np.nan,2])
df = pd.DataFrame({'A':a,'B':b,'C':c,'D':d,'E':e, 'F':f})
df.ix[3:6,'A']=np.nan
df.ix[4:8,'C']=np.nan

编辑

keys=['S01_o4584','S02_o2531','S03_o7812','S03_o1122','S04_o5210','S04_o3212','S05_o4665','S06_o7425','S07_o3689','S08_o2371']
df['index']=keys
df = df.set_index('index')

A B C D E F
index
S01_o4584 8.0 NaN 9.0 7.0 NaN NaN
S02_o2531 8.0 2.0 5.0 2.0 2.0 2.0
S03_o7812 1.0 NaN 5.0 NaN NaN NaN
S03_o1122 NaN 3.0 6.0 NaN NaN 3.0
S04_o5210 NaN NaN NaN NaN NaN 7.0
S04_o3212 NaN 6.0 NaN 6.0 6.0 NaN
S05_o4665 NaN 8.0 NaN 8.0 8.0 8.0
S06_o7425 1.0 1.0 NaN NaN NaN NaN
S07_o3689 8.0 2.0 NaN 2.0 NaN NaN
S08_o2371 3.0 NaN 9.0 2.0 2.0 2.0

如您所见,B 列、D 列(以及新的 E 列)在位置(索引)S02_o2531、S04_o3212、S05_o4665 和 S08_o2371 具有相同的值,而在其他位置,其中一个具有值,而其他有 s NaN。

我想要的输出是:

index   BD*E*
S01_o4584 7
S02_o2531 2
S03_o7812 NaN
S03_o1122 3
S04_o5210 NaN
S04_o3212 6
S05_o4665 8
S06_o7425 1
S07_o3689 2
S08_o2371 2

但是,我无法合并在索引的同一开头具有两个不同值的列:如您所见,列 F 也共享一些索引,但新索引位于 S04_o5210,但之前的组合列已在“S04_”处有一个值(索引 S04_o3212)。

有没有一种相当Pythonic的方法来做到这一点? IE。 1)根据其中的值必须相同或np.nan而不是不同的条件查找列。 2)设置一个条件,如果列与先前包含的值的索引具有相同的开头,则不能合并(我可能需要将字符串拆分为两列并执行多重索引???) 3)将它们合并到新的列中系列/数据框。

最佳答案

def almost(df):
i, j = np.triu_indices(len(df.columns), 1)

v = df.values

d = v[:, i] - v[:, j]
m = (np.where(np.isnan(d), 0, d) == 0).all(0)

return pd.concat(
[
df.iloc[:, i_].combine_first(
df.iloc[:, j_]
).rename(
tuple(df.columns[[i_, j_]])
) for i_, j_ in zip(i[m], j[m])],
axis=1
)

almost(df)

B
D
0 7.0
1 2.0
2 NaN
3 3.0
4 NaN
5 6.0
6 8.0
7 1.0
8 2.0
9 2.0

它是如何工作的

  • ij 表示使用 numpy 获取上三角形索引的每个列组合。
  • 使用 ij 对底层 numpy 数组 df.values 进行切片,然后将它们相减。如果差异为 nan,则表示其中一个为 nan。否则,如果各个元素相同,则差异应为零。
  • 由于我们可以容忍其中之一的 nan,因此使用 np.where 将它们填充为零。
  • 使用 (x == 0).all(0) 查找所有行均为零的位置。
  • 使用上面的掩码对 ij 进行切片并识别匹配的列。
  • 使用 pd.MultiIndex 为显示匹配项的列构建所有匹配项的数据框。

更酷的示例

np.random.seed([3,1415])
m, n = 20, 26
df = pd.DataFrame(
np.random.randint(10, size=(m, n)),
columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
).mask(np.random.choice([True, False], (m, n), p=(.6, .4)))

df

enter image description here

almost(df)

A D G H I J K
J X K M N J K V S X
0 6.0 7.0 3.0 NaN 4.0 6.0 NaN 6.0 NaN 7.0
1 3.0 3.0 2.0 6.0 4.0 NaN 2.0 6.0 2.0 2.0
2 3.0 0.0 NaN 2.0 4.0 3.0 NaN 3.0 4.0 0.0
3 4.0 4.0 3.0 5.0 5.0 4.0 3.0 4.0 3.0 3.0
4 7.0 NaN NaN 7.0 3.0 7.0 NaN 7.0 NaN NaN
5 NaN NaN 2.0 0.0 5.0 NaN 2.0 2.0 2.0 2.0
6 NaN 8.0 NaN NaN 9.0 2.0 2.0 1.0 NaN 8.0
7 NaN 7.0 NaN 9.0 9.0 6.0 6.0 NaN NaN 7.0
8 NaN NaN 8.0 3.0 1.0 NaN NaN NaN 4.0 NaN
9 0.0 0.0 8.0 2.0 NaN 3.0 3.0 NaN NaN NaN
10 0.0 0.0 NaN 6.0 1.0 NaN NaN 8.0 NaN NaN
11 NaN NaN 3.0 NaN 9.0 3.0 3.0 NaN 3.0 3.0
12 5.0 NaN NaN NaN 6.0 5.0 NaN 5.0 8.0 NaN
13 NaN NaN NaN NaN 7.0 5.0 5.0 NaN NaN NaN
14 NaN NaN 6.0 4.0 8.0 8.0 8.0 NaN 0.0 NaN
15 8.0 8.0 7.0 NaN NaN NaN NaN NaN 2.0 NaN
16 4.0 4.0 4.0 4.0 9.0 9.0 9.0 6.0 4.0 NaN
17 NaN 4.0 NaN 4.0 2.0 8.0 8.0 4.0 NaN 4.0
18 NaN NaN 2.0 7.0 NaN NaN NaN NaN NaN NaN
19 NaN 7.0 6.0 3.0 5.0 NaN NaN 7.0 NaN 7.0

关于python - 有没有办法获得 pandas DataFrame 的几列的 "union"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43195757/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com