我是新手使用熊猫但想要更好地学习它。我目前正面临一个问题。我有一个看起来像这样的DataFrame:
0 1 2
0 chr2L 1 4
1 chr2L 9 12
2 chr2L 17 20
3 chr2L 23 23
4 chr2L 26 27
5 chr2L 30 40
6 chr2L 45 47
7 chr2L 52 53
8 chr2L 56 56
9 chr2L 61 62
10 chr2L 66 80
我想得到这样的东西:
0 1 2 3
0 chr2L 0 1 0
1 chr2L 1 2 1
2 chr2L 2 3 1
3 chr2L 3 4 1
4 chr2L 4 5 0
5 chr2L 5 6 0
6 chr2L 6 7 0
7 chr2L 7 8 0
8 chr2L 8 9 0
9 chr2L 9 10 1
10 chr2L 10 11 1
11 chr2L 11 12 1
12 chr2L 12 13 0
And so on...
因此,用零填充缺失的区间,并将当前区间保存为1(如果有一种简单的方法可以保存"边界"位置(初始数据中区间的边界)为同时0.5也可能有帮助)将所有数据分成1个长度的间隔。
在数据中,第0列中有多个字符串值,应分别对每个字符串值进行此操作。它们需要不同长度的最终数据(应该得到0或1的最后一个值是不同的)。非常感谢您在熊猫中处理此问题的帮助。
答案 0 :(得分:1)
这适用于您的第一段和大部分第二段。作为练习留下:完成插入insideness=0
行(见结束):
import pandas as pd
# dummied-up version of your data, but with column headers for readability:
df = pd.DataFrame({'n':['a']*4 + ['b']*2, 'a':[1,6,8,5,1,5],'b':[4,7,10,5,3,7]})
# splitting up a range, translated into df row terms:
def onebyone(dfrow):
a = dfrow[1].a; b = dfrow[1].b; n = dfrow[1].n
count = b - a
if count >= 2:
interior = [0.5]+[1]*(count-2)+[0.5]
elif count == 1:
interior = [0.5]
elif count == 0:
interior = []
return {'n':[n]*count, 'a':range(a, a + count),
'b':range(a + 1, a + count + 1),
'insideness':interior}
编辑使用pandas 0.15中的新增pd.concat()
来合并中间结果:
# Into a new dataframe:
intermediate = []
for label in set(df.n):
for row in df[df.n == label].iterrows():
intermediate.append(pd.DataFrame(onebyone(row)))
df_onebyone = pd.concat(intermediate)
df_onebyone.index = range(len(df_onebyone))
最后是一个识别缺失行的草图,您可以编辑该行以匹配上述for循环,将行添加到最终数据帧中:
# for times in the overall range describing 'a'
for i in range(int(newd[newd.n=='a'].a.min()),int(newd[newd.n=='a'].a.max())):
# if a time isn't in an existing 0.5-1-0.5 range:
if i not in newd[newd.n=='a'].a.values:
# these are the values to fill in a 0-row
print '%d, %d, 0'%(i, i+1)
或者,如果您知道将为每个a
排序n
列,您可以跟踪onebyone()处理的最后一个结束值,并插入一些额外的行以赶上您将要传递给onebyone()的下一个起始值。