熊猫数据框遍历行

时间:2019-12-16 23:58:40

标签: python pandas

我有一个数据框,其中X和Y是细胞坐标,mRNA是每个细胞的mRNA数量。

        ID        X        Y  mRNA
0        0  149.492  189.153     0
1        1  115.084  194.082     2
2        2  135.331  194.831     7
3        3  136.965  184.493     2
4        4  124.025  190.069     1
...    ...      ...      ...   ...
2410  2410  452.596  256.313     0
2411  2411  196.448  333.959    46
2412  2412  190.779  318.418    71
2413  2413  202.941  335.446    37
2414  2414  254.967  369.431    13

目前,我正在尝试应用此公式,但我无法使其真正起作用。理想情况下,我想执行此操作:

For ID 0: sqrt[((X0-X1)^2)+((Y0-Y1)^2)]
          sqrt[((X0-X2)^2)+((Y0-Y2)^2)]
          ............
          sqrt[((X0-Xn)^2)+((Y0-Yn)^2)]

(where n is the last cell ID in my csv file 2414)

然后必须对所有单元格的ID 1执行相同的操作,然后是ID 2,依此类推。

import pandas as pd
import numpy as np

df=pd.read_csv('Detailed2.csv', sep=',')
print(df)

df1 = np.sqrt(((df['X'].sub(df['X']))^2).add((df['Y'].sub(df['Y']))^2)).to_frame('col')
print(df1)

此代码不起作用。

3 个答案:

答案 0 :(得分:3)

使用:

==

输出

=

使用for Id in df['ID']: df[f'new_col_{Id}']=( df[['X','Y']].sub(df.loc[df['ID'].eq(Id),['X','Y']].values) .pow(2) .sum(axis=1) .pow(1/2) ) print(df) @Trenton McKinney和@AlexanderCécile的解决方案(推荐)

          ID        X        Y  mRNA   new_col_0   new_col_1   new_col_2  \
0        0  149.492  189.153     0    0.000000   34.759251   15.256920   
1        1  115.084  194.082     2   34.759251    0.000000   20.260849   
2        2  135.331  194.831     7   15.256920   20.260849    0.000000   
3        3  136.965  184.493     2   13.365677   23.889895   10.466337   
4        4  124.025  190.069     1   25.483468    9.800288   12.267937   
2410  2410  452.596  256.313     0  310.455311  343.201176  323.167320   
2411  2411  196.448  333.959    46  152.228918  161.819886  151.960153   
2412  2412  190.779  318.418    71  135.698403  145.565016  135.455628   
2413  2413  202.941  335.446    37  155.751204  166.441079  156.024647   
2414  2414  254.967  369.431    13  208.866304  224.308996  211.655221   

       new_col_3   new_col_4  new_col_2410  new_col_2411  new_col_2412  \
0      13.365677   25.483468    310.455311    152.228918    135.698403   
1      23.889895    9.800288    343.201176    161.819886    145.565016   
2      10.466337   12.267937    323.167320    151.960153    135.455628   
3       0.000000   14.090258    323.698997    160.867375    144.332436   
4      14.090258    0.000000    335.182293    161.088246    144.670530   
2410  323.698997  335.182293      0.000000    267.657802    269.082093   
2411  160.867375  161.088246    267.657802      0.000000     16.542679   
2412  144.332436  144.670530    269.082093     16.542679      0.000000   
2413  164.741133  165.415257    261.896259      6.661097     20.925272   
2414  219.377610  222.073264    227.712326     68.430521     81.990399   

      new_col_2413  new_col_2414  
0       155.751204    208.866304  
1       166.441079    224.308996  
2       156.024647    211.655221  
3       164.741133    219.377610  
4       165.415257    222.073264  
2410    261.896259    227.712326  
2411      6.661097     68.430521  
2412     20.925272     81.990399  
2413      0.000000     62.142457  
2414     62.142457      0.000000 

适用的解决方案

itertuples

请记住,您不能重复输入ID

答案 1 :(得分:1)

我建议改用底层的numpy数组和scipy的distance_matrix

from scipy.spatial import distance_matrix

arr = df[["X", "Y"]].to_numpy()
dists = distance_matrix(arr, arr)
dist_col_names = "dist_to_" + df["ID"].astype("str")
for col_name, col in zip(dist_col_names, dists):
    df[col_name] = col

与循环遍历行相比,这可能会提高速度。

答案 2 :(得分:1)

在我从事我的工作时,PMende发布了NumPy解决方案,而且效果甚至更好。对他表示敬意。


我喜欢他的回答略有不同,因为它不使用任何显式循环。

raw_str = \
    '''
            ID        X        Y  mRNA
    0        0  149.492  189.153     0
    1        1  115.084  194.082     2
    2        2  135.331  194.831     7
    3        3  136.965  184.493     2
    4        4  124.025  190.069     1
    2410  2410  452.596  256.313     0
    2411  2411  196.448  333.959    46
    2412  2412  190.779  318.418    71
    2413  2413  202.941  335.446    37
    2414  2414  254.967  369.431    13
    '''

df_1 = pd.read_csv(StringIO(raw_str), header=0, delim_whitespace=True, usecols=[1, 2, 3, 4])

coords = df_1[['X', 'Y']].to_numpy()

distances = spsp.distance_matrix(coords, coords)

col_names = df_1['ID'].map(lambda x: f'col_id_{x}').rename()

df_2 = pd.DataFrame(data=distances, columns=col_names)

df_3 = pd.concat((df_1, df_2), axis=1)

多余的变量显然会影响性能,在这里只是为了清楚起见。


创建数千个列有点疯狂,这是一种更合理的解决方案,可以将距离保存为每一行中的列表。

from io import StringIO

import pandas as pd
import scipy.spatial as spsp

raw_str = \
    '''
            ID        X        Y  mRNA
    0        0  149.492  189.153     0
    1        1  115.084  194.082     2
    2        2  135.331  194.831     7
    3        3  136.965  184.493     2
    4        4  124.025  190.069     1
    2410  2410  452.596  256.313     0
    2411  2411  196.448  333.959    46
    2412  2412  190.779  318.418    71
    2413  2413  202.941  335.446    37
    2414  2414  254.967  369.431    13
    '''

df_1 = pd.read_csv(StringIO(raw_str), header=0, delim_whitespace=True, usecols=[1, 2, 3, 4])

coords = df_1[['X', 'Y']].to_numpy()

distances = spsp.distance_matrix(coords, coords)

df_1['dist'] = distances.tolist()

df_1

     ID        X  ...  mRNA                                               dist
0     0  149.492  ...     0  [0.0, 34.759250639218344, 15.256919905406859, ...
1     1  115.084  ...     2  [34.759250639218344, 0.0, 20.26084919246971, 2...
2     2  135.331  ...     7  [15.256919905406859, 20.26084919246971, 0.0, 1...
3     3  136.965  ...     2  [13.36567727427235, 23.889894976746966, 10.466...
4     4  124.025  ...     1  [25.483468072458283, 9.800288261066603, 12.267...
5  2410  452.596  ...     0  [310.45531146366295, 343.201176433007, 323.167...
6  2411  196.448  ...    46  [152.2289183171187, 161.81988637061886, 151.96...
7  2412  190.779  ...    71  [135.69840306355857, 145.56501613025023, 135.4...
8  2413  202.941  ...    37  [155.75120368716253, 166.4410794996235, 156.02...
9  2414  254.967  ...    13  [208.86630390994137, 224.30899556192568, 211.6...