Pandas DataFrame [cell=(label,value)],分成 2 个单独的数据框
Posted
技术标签:
【中文标题】Pandas DataFrame [cell=(label,value)],分成 2 个单独的数据框【英文标题】:Pandas DataFrame [cell=(label,value)], split into 2 separate dataframes 【发布时间】:2016-08-12 06:58:38 【问题描述】:我找到了一个很棒的方法来parse
html
和pandas
。我的数据是一种奇怪的格式(附在下面)。我想将此数据拆分为 2 个单独的 dataframes
。
注意每个cell
是如何被,
分隔的... 有没有真正有效的方法来拆分所有这些单元格并创建2 个数据帧,一个用于标签,一个用于( value )
在括号中?
NumPy
拥有所有这些ufuncs
,有没有办法可以在string
dtypes
上使用它们,因为它们可以使用DF.as_matrix()
转换为np.array
?我试图避开for loops
,我可以遍历所有索引并填充一个空数组,但这很野蛮。
我正在使用Beaker Notebook
btw,真的很酷(强烈推荐)
#Set URL Destination
url = "http://www.reef.org/print/db/stats"
#Process raw table
DF_raw = pd.pandas.read_html(url)[0]
#Get start/end indices of table
start_label = "10 Most Frequent Species"; start_idx = (DF_raw.iloc[:,0] == start_label).argmax()
end_label = "Top 10 Sites for Species Richness"; end_idx = (DF_raw.iloc[:,0] == end_label).argmax()
#Process table
DF_freqSpecies = pd.DataFrame(
DF_raw.as_matrix()[(start_idx + 1):end_idx,:],
columns = DF_raw.iloc[0,:]
)
DF_freqSpecies
#Split these into 2 separate DataFrames
这是我的幼稚做法:
import re
DF_species = pd.DataFrame(np.zeros_like(DF_freqSpecies),columns=DF_freqSpecies.columns)
DF_freq = pd.DataFrame(np.zeros_like(DF_freqSpecies).astype(str),columns=DF_freqSpecies.columns)
dims = DF_freqSpecies.shape
for i in range(dims[0]):
for j in range(dims[1]):
#Parse current dataframe
species, freq = re.split("\s\(\d",DF_freqSpecies.iloc[i,j])
freq = float(freq[:-1])
#Populate split DataFrames
DF_species.iloc[i,j] = species
DF_freq.iloc[i,j] = freq
我想要这 2 个数据帧作为我的输出:
(1) 物种; (2) 频率
【问题讨论】:
您可以发布所需的输出 DF 吗?目前还不清楚你想要实现什么 是的,让我通过迭代快速计算它们。 它现在在上面@MaxU 【参考方案1】:你可以这样做:
DF1:
In [182]: df1 = DF_freqSpecies.replace(r'\s*\(\d+\.*\d*\)', '', regex=True)
In [183]: df1.head()
Out[183]:
0 Tropical Western Atlantic California, Pacific Northwest and Alaska \
0 Bluehead Copper Rockfish
1 Blue Tang Lingcod
2 Stoplight Parrotfish Painted Greenling
3 Bicolor Damselfish Sunflower Star
4 French Grunt Plumose Anemone
0 Hawaii Tropical Eastern Pacific \
0 Saddle Wrasse King Angelfish
1 Hawaiian Whitespotted Toby Mexican Hogfish
2 Raccoon Butterflyfish Barberfish
3 Manybar Goatfish Flag Cabrilla
4 Moorish Idol Panamic Sergeant Major
0 South Pacific Northeast US and Eastern Canada \
0 Regal Angelfish Cunner
1 Bluestreak Cleaner Wrasse Winter Flounder
2 Manybar Goatfish Rock Gunnel
3 Brushtail Tang Pollock
4 Two-spined Angelfish Grubby Sculpin
0 South Atlantic States Central Indo-Pacific
0 Slippery Dick Moorish Idol
1 Belted Sandfish Three-spot Dascyllus
2 Black Sea Bass Bluestreak Cleaner Wrasse
3 Tomtate Blacklip Butterflyfish
4 Cubbyu Clark's Anemonefish
和DF2
In [193]: df2 = DF_freqSpecies.replace(r'.*\((\d+\.*\d*)\).*', r'\1', regex=True)
In [194]: df2.head()
Out[194]:
0 Tropical Western Atlantic California, Pacific Northwest and Alaska Hawaii \
0 85 54.6 92
1 84.8 53.2 85.8
2 81 50.8 85.7
3 79.9 50.2 85.7
4 74.8 49.7 82.9
0 Tropical Eastern Pacific South Pacific Northeast US and Eastern Canada \
0 85.7 79 67.4
1 82.5 77.3 46.6
2 75.2 73.9 26.2
3 68.9 73.3 25.2
4 67.9 72.8 23.7
0 South Atlantic States Central Indo-Pacific
0 79.7 80.1
1 78.5 75.6
2 78.5 73.5
3 72.7 71.4
4 65.7 70.2
RegEx debugging and explanation:
我们基本上想删除所有内容,除了括号中的数字:
(\d+\.*\d*)
- group(1) - 这是我们的号码
\((\d+\.*\d*)\)
- 括号中的数字
.*\((\d+\.*\d*)\).*
- 整个事情 - '(', '(', our number, ')' 之前的任何内容,直到单元格末尾的任何内容
它将被替换为 group(1) - 我们的号码
【讨论】:
2 行!惊人的。你能解释一下r'.*\((\d+\.*\d*)\).*', r'\1'
发生了什么吗?我理解另一个,但这个很混乱。
@O.rka,我已经为 RegEx 部分添加了解释
@MaxU @O.rka 小心,第一个替换会吃掉括号中的所有内容,例如DF_freqSpecies.loc[9,'Hawaii']
。
@MaxU 还有一件小事 :-) 在第一次替换中,您可以在正则表达式中添加一个空格:r' \(\d+\.*\d*\)'
。它在输出中尾随。以上是关于Pandas DataFrame [cell=(label,value)],分成 2 个单独的数据框的主要内容,如果未能解决你的问题,请参考以下文章
如何更改 Pandas Dataframe 的形状(带有“L”的行号)?
将两个 pandas 数据帧组合成一个数据帧“dict type cell”(pd.Panel 已弃用)