下面列出了一个非常非结构化的数据框架。其目标是将信息组合成5行dataframe(将0-3、4-8、9-10、11-15和16行中的项目中的字符串组合起来;代码在同一行集中;代码不是唯一的)。我能够获得起始索引的索引(0,4,9,11,16……;-起始行的前一行具有值为‘nan’的列‘代码’),而无需使用for循环。但是我想不出一种不用for循环来组合这些行的方法。有人能帮忙吗?谢谢!
code item01 item02 item03 item04 item05
0 1111 'a' 123 234 345 440
1 1111 'b' nan nan nan nan
2 nan 'c' nan nan nan nan
3 nan 'd' nan nan nan nan
4 2222 'b' 123 234 345 456
5 2222 'b' nan nan nan nan
6 nan 'c' nan nan nan nan
7 nan 'd' nan nan nan nan
8 nan 'e' nan nan nan nan
9 3333 'd' 123 234 345 456
10 nan 'b' nan nan nan nan
11 1111 'c' 123 234 345 456
12 1111 'b' nan nan nan nan
13 nan 'c' nan nan nan nan
14 nan 'd' nan nan nan nan
15 nan 'e' nan nan nan nan
16 5555 'a' nan nan nan nan预期成果:
code item01 item02 item03 item04 item05
0 1111 'abcd' 123 234 345 440
1 2222 'bbcde' 123 234 345 456
2 3333 'db' 123 234 345 456
3 1111 'cbcde' 123 234 345 456
4 5555 'a' 123 234 345 456发布于 2019-07-19 17:38:09
如果你定义
code_notnull = pd.notnull(df['code']) 然后,您可以使用以下方法识别每个新组的开始
# True when the row is not null, but the prior row is null
mask = code_notnull & ~(code_notnull.shift(1, fill_value=False))
0 True
1 False
2 False
3 False
4 True
...然后,您可以使用
group_num = mask.cumsum()
0 1
1 1
2 1
3 1
4 2
...然后用group_num分组
import numpy as np
import pandas as pd
nan = np.nan
df = pd.DataFrame({'code': [1111.0, 1111.0, nan, nan, 2222.0, 2222.0, nan, nan, nan, 3333.0, nan,
1111.0, 1111.0, nan, nan, nan, 5555.0], 'item01': ['a', 'b', 'c', 'd',
'b', 'b', 'c', 'd', 'e', 'd', 'b', 'c', 'b', 'c', 'd',
'e', 'a'], 'item02': [123.0, nan, nan, nan, 123.0, nan, nan, nan, nan,
123.0, nan, 123.0, nan, nan, nan, nan, nan], 'item03': [234.0, nan, nan, nan,
234.0, nan, nan, nan, nan, 234.0, nan, 234.0, nan, nan, nan, nan, nan],
'item04': [345.0, nan, nan, nan, 345.0, nan, nan, nan, nan, 345.0, nan, 345.0,
nan, nan, nan, nan, nan], 'item05': [440.0, nan, nan, nan, 456.0, nan, nan,
nan, nan, 456.0, nan, 456.0, nan, nan, nan, nan, nan]})
code_notnull = pd.notnull(df['code'])
mask = code_notnull & ~(code_notnull.shift(1, fill_value=False))
group_num = mask.cumsum()
# Forward-fill all NaNs.
df = df.ffill()
grouped = df.groupby(group_num)
result = grouped.first()
result['item01'] = grouped['item01'].sum()
print(result)收益率
code item01 item02 item03 item04 item05
code
1 1111.0 abcd 123.0 234.0 345.0 440.0
2 2222.0 bbcde 123.0 234.0 345.0 456.0
3 3333.0 db 123.0 234.0 345.0 456.0
4 1111.0 cbcde 123.0 234.0 345.0 456.0
5 5555.0 a 123.0 234.0 345.0 456.0注意,上面我假设您在item01中的字符串不以单引号开头和结尾。如果他们这么做了,你可以用
df['item01'] = df['item01'].str[1:-1]然后按照上面的方式进行。
import numpy as np
import pandas as pd
nan = np.nan
df = pd.DataFrame({'code': [1111.0, 1111.0, nan, nan, 2222.0, 2222.0, nan, nan, nan, 3333.0, nan,
1111.0, 1111.0, nan, nan, nan, 5555.0], 'item01': ["'a'", "'b'", "'c'", "'d'",
"'b'", "'b'", "'c'", "'d'", "'e'", "'d'", "'b'", "'c'", "'b'", "'c'", "'d'",
"'e'", "'a'"], 'item02': [123.0, nan, nan, nan, 123.0, nan, nan, nan, nan,
123.0, nan, 123.0, nan, nan, nan, nan, nan], 'item03': [234.0, nan, nan, nan,
234.0, nan, nan, nan, nan, 234.0, nan, 234.0, nan, nan, nan, nan, nan],
'item04': [345.0, nan, nan, nan, 345.0, nan, nan, nan, nan, 345.0, nan, 345.0,
nan, nan, nan, nan, nan], 'item05': [440.0, nan, nan, nan, 456.0, nan, nan,
nan, nan, 456.0, nan, 456.0, nan, nan, nan, nan, nan]})
df['item01'] = df['item01'].str[1:-1]
print(df)收益率( df['item0']中的单引号已经删除)
code item01 item02 item03 item04 item05
0 1111.0 a 123.0 234.0 345.0 440.0
1 1111.0 b NaN NaN NaN NaN
2 NaN c NaN NaN NaN NaN
3 NaN d NaN NaN NaN NaN
...如果要将单引号添加回最终结果,可以使用:
result['item01'] = "'" + result['item01'] + "'"发布于 2019-07-19 17:03:32
在创建了一个具有唯一代码的有效分组列之后,可以使用groupby完成此操作。
如果每个组的所有行都是连续的,并且标识一个新组的逻辑是:
起始行的前一行具有值为“nan”的列
'code'。
您只需检查上一个代码值为空时,代码值是否为空。您可以通过将'code'列移动一个,并使用列表检查移位列和原始列的值来实现这一点。
然后,累积和将为分组创建唯一值。
df['uniquecode'] = [pd.notnull(curr) and pd.isnull(prev) for curr, prev in zip(df['code'], df['code'].shift(1))]
df['uniquecode'] = df['uniquecode'].cumsum()
ddf = df.groupby('uniquecode').agg({'code':'mean', 'item01':'sum', 'item02':'sum', 'item03':'sum', 'item04':'sum', 'item05':'sum'}))
ddf['item01'] = ddf['item01'].apply(lambda x : "'" + x.replace("'","") + "'")这将返回ddf
code item01 item02 item03 item04 item05
uniquecode
1 1111.0 'abcd' 123.0 234.0 345.0 440.0
2 2222.0 'bbcde' 123.0 234.0 345.0 456.0
3 3333.0 'db' 123.0 234.0 345.0 456.0
4 1111.0 'cbcde' 123.0 234.0 345.0 456.0
5 5555.0 'a' 0.0 0.0 0.0 0.0最后一行使用apply删除未嵌套的'字符,因为所有字符都被顶点包围。
您可以通过执行'uniquecode'索引来消除ddf.reset_index(drop=True, inplace=True)索引
发布于 2019-07-19 17:49:05
如果这段代码对你有用,你能检查一下吗?(我编辑了代码)
df1=df.ffill()
df1['prev_code']=df1['code'].shift(1)
df1['grkey']=df1.reset_index().apply(lambda x: x['index'] if x.code!=x.prev_code else float('nan'), axis=1)
df1=df1.ffill().groupby('grkey').agg({'code':'first', 'item01':'sum','item02':'first','item03':'first','item04':'first','item05':'first'}).reset_index().drop('grkey',axis=1)
df1['item01']=df1['item01'].apply(lambda x: x.replace("''",""))https://stackoverflow.com/questions/57116490
复制相似问题