将某些列转换为不同的数据类型并过滤这些列

时间:2016-07-08 11:46:21

标签: python numpy pandas dataframe

我有一个数据框,如下所示,

enter image description here

我需要将那些以Distance *开头的列转换为数据类型整数(目前它们是字符串格式),然后进一步过滤那些。

我可以这样做,分别为每一列,但我的数据框很大,有很多列

a.Distance0=a.Distance0.astype(int)
a.Distance1=a.Distance1.astype(int)

此后,我需要根据以Distance开头的列过滤掉这些行,得到两列作为输出,所以我作为输入数据框的最终输出是,

 Head1     Header   Dis
    ABC    SAP     115590
    ABC    GRN     426250
    KLM    DSQ    120001

我试图使用下面的代码到达那里,那就是我正在过滤那些以Distance> = 100000开头的行,而我只想要那些具有三列值的行,如上所述。    这是我尝试过的,但是这个解决方案给了我所有的列

a.loc[a[a[a.columns[pd.Series(a.columns).str.startswith('Distance')]] >= 100000].dropna(how='all', axis=0).index]

但是它给出了结果,但我得到的所有列都是这样的,

RNA             PC                  NA  PC0   Strand0 Distance0   PC1 Strand1 Distance1
RP11 RNF223 (+11559), AGRN (+42625) 0   RNF223  +   115590  AGRN    +   42625
RP13 CORT (-19440), APITD1 (+177)   0   CORT    -   254880  APITD1  +   177

任何帮助或建议都会非常棒。!!!

2 个答案:

答案 0 :(得分:1)

如果要更改以Distance开头的每列的类型,可以使用循环:

list_col = []
for col in a.columns:
    if (len(col) > 8) & (col[:8] == 'Distance'):
        list_col.appen(col)
a[list_col] = a[list_col].astype(int)

然后创建一个连接不同Distance值的数据帧:

frames = []
for i in len(list_col):
    temp = df[['Head1','Header'+str(i),list_col[i]]]
    temp.columns = ['Head1','Header','Distance']
    frames.append(temp)
output = pd.concat(drames)

(请注意,这意味着您的列名称要格式良好,您可能需要根据append中的实际名称进行调整)

然后你过滤:

output = out[out.Distance >= 100000]

这可能在您第一次尝试使用数据帧时无效,因为我假设您的数据帧列(只有我们感兴趣的列)被调用如下:

Head1      Header0    Distance0     Header1    Distance1    Header2    Distance2

依此类推......(再一次,我们不关心其他专栏,因为他们不会干涉此代码)

答案 1 :(得分:1)

请注意,我已将您的第一个Head1列重命名为Header(您的示例中有重复的列)。

我设置的Dataframe与您的不同,但足够接近。我没有填写与问题无关的专栏。

这是我的设置代码:

import pandas as pd

df = pd.DataFrame([],
                   columns=["Header",
                   "LongHeader",
                   "Head0",
                   "Strand0",
                   "Distance0",
                   "Head1",
                   "Strand1",
                   "Distance1",
                   "Head2",
                   "Strand2",
                   "Distance2"])
df["Header"] = ["ABC", "EFG", "HIJ", "KLM", "SOS"]
df["LongHeader"] = ["1", "2", "3", "4", "5"]
df["Head0"] = ["SAP", "HES3", "CORT", "AAD", "MFA"]
df["Strand0"] = ["+", "-", "-", "-", "-"]
df["Distance0"] = ["115590", "6350", "19440", "25488", "11174"]
df["Head1"] = ["GRN", "CMT", "API", "DH", "13A2"]
df["Strand1"] = ["+", "-", "-", "-", "-"]
df["Distance1"] = ["426250", "1902", "177", "1341", "19763"]
df["Head2"] = ["None", "None", "None", "DSQ", "None"]
df["Strand2"] = ["+", "-", "-", "-", "-"]
df["Distance2"] = ["None", "None", "None", "120001", "None"]

print df

其中的数据类似于您的示例:

  Header LongHeader Head0 Strand0 Distance0 Head1 Strand1 Distance1 Head2  
0    ABC          1   SAP       +    115590   GRN       +    426250  None   
1    EFG          2  HES3       -      6350   CMT       -      1902  None   
2    HIJ          3  CORT       -     19440   API       -       177  None   
3    KLM          4   AAD       -     25488    DH       -      1341   DSQ   
4    SOS          5   MFA       -     11174  13A2       -     19763  None 

这是执行工作的代码。主要思想是提取Headx和Distancex列,并将它们叠加在一起。然后将Distance的dtype更改为int,并且仅保留Distance> gt = = 100000的行。

frames_to_concat = []
for col in df:
    if col.startswith("Dis"):
        dis_num = col[-1] # Extract the # from a column like Distance# or Dis#
        frame_to_concat = df[["Header", "Head" + dis_num, "Distance" + dis_num]]
        frame_to_concat.columns = ["Header", "Head", "Distance"]
        frames_to_concat.append(frame_to_concat)

stacked_columns = pd.concat(frames_to_concat)
stacked_columns = stacked_columns[stacked_columns["Distance"] != "None"]
stacked_columns["Distance"] = stacked_columns["Distance"].astype(int)
result = stacked_columns[stacked_columns["Distance"] > 100000]

print result

给出了:

# Output:
  Header Head  Distance
0    ABC  SAP    115590
0    ABC  GRN    426250
3    KLM  DSQ    120001

下次你问一个问题时,不要让潜在的回答者如此努力。提供设置代码!!!

您必须稍微修改此解决方案以与您的实际列名对齐,我不确定由于重复列问题而应该实际调用它们。 HTH!