版本 0.16.1(2015年5月11日)#
这是 0.16.0 的一个次要错误修复版本,包含了大量错误修复以及多项新功能、增强功能和性能改进。我们建议所有用户升级到此版本。
亮点包括
支持
CategoricalIndex
,一种基于类别的索引,详见 此处新增关于如何为 pandas 贡献的章节,详见 此处
修订后的“合并、连接和拼接”文档,包含图示示例,以便更容易理解各项操作,详见 此处
新增 `sample` 方法,用于从 Series、DataFrames 和 Panels 中抽取随机样本。详见 此处
默认的
Index
打印格式已更改为更统一的格式,详见 此处现在支持
BusinessHour
日期时间偏移量,详见 此处进一步增强了
.str
访问器,使字符串操作更简便,详见 此处
v0.16.1 中的新特性
警告
在 pandas 0.17.0 中,`pandas.io.data` 子包将被移除,取而代之的是一个可单独安装的包(GH 8961)。
增强功能#
CategoricalIndex#
我们引入了 CategoricalIndex
,这是一种新型索引对象,对于支持重复值索引非常有用。它是 Categorical
(在 v0.15.0 中引入)的封装,可以高效地索引和存储包含大量重复元素的索引。在 0.16.1 之前,使用 category
数据类型设置 DataFrame/Series
的索引会将其转换为常规的基于对象的 Index
。
In [1]: df = pd.DataFrame({'A': np.arange(6),
...: 'B': pd.Series(list('aabbca'))
...: .astype('category', categories=list('cab'))
...: })
...:
In [2]: df
Out[2]:
A B
0 0 a
1 1 a
2 2 b
3 3 b
4 4 c
5 5 a
In [3]: df.dtypes
Out[3]:
A int64
B category
dtype: object
In [4]: df.B.cat.categories
Out[4]: Index(['c', 'a', 'b'], dtype='object')
设置索引时,将创建 CategoricalIndex
In [5]: df2 = df.set_index('B')
In [6]: df2.index
Out[6]: CategoricalIndex(['a', 'a', 'b', 'b', 'c', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
使用 __getitem__/.iloc/.loc/.ix
进行索引与具有重复值的 Index 类似。索引器必须属于该类别,否则操作将引发错误。
In [7]: df2.loc['a']
Out[7]:
A
B
a 0
a 1
a 5
并保留 CategoricalIndex
In [8]: df2.loc['a'].index
Out[8]: CategoricalIndex(['a', 'a', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
排序将按照类别的顺序进行
In [9]: df2.sort_index()
Out[9]:
A
B
c 4
a 0
a 1
a 5
b 2
b 3
对索引进行 groupby 操作也将保留索引的性质
In [10]: df2.groupby(level=0).sum()
Out[10]:
A
B
c 4
a 6
b 5
In [11]: df2.groupby(level=0).sum().index
Out[11]: CategoricalIndex(['c', 'a', 'b'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
重新索引操作将根据传入的索引器类型返回一个结果索引,这意味着传入一个列表将返回一个普通的 Index
;使用 Categorical
进行索引将返回一个 CategoricalIndex
,其索引根据传入的 Categorical
数据类型类别进行。这允许即使索引器值不在类别中也能任意索引,类似于您可以重新索引任何 pandas 索引的方式。
In [12]: df2.reindex(['a', 'e'])
Out[12]:
A
B
a 0.0
a 1.0
a 5.0
e NaN
In [13]: df2.reindex(['a', 'e']).index
Out[13]: pd.Index(['a', 'a', 'a', 'e'], dtype='object', name='B')
In [14]: df2.reindex(pd.Categorical(['a', 'e'], categories=list('abcde')))
Out[14]:
A
B
a 0.0
a 1.0
a 5.0
e NaN
In [15]: df2.reindex(pd.Categorical(['a', 'e'], categories=list('abcde'))).index
Out[15]: pd.CategoricalIndex(['a', 'a', 'a', 'e'],
categories=['a', 'b', 'c', 'd', 'e'],
ordered=False, name='B',
dtype='category')
Sample 方法#
Series、DataFrames 和 Panels 现在有了一个新方法:sample()
。该方法接受要返回的特定行数或列数,或总行数或列数的一个分数。它还提供了有放回或无放回抽样、为非均匀抽样传入权重列以及设置种子值以方便复现的选项。(GH 2419)
In [1]: example_series = pd.Series([0, 1, 2, 3, 4, 5])
# When no arguments are passed, returns 1
In [2]: example_series.sample()
Out[2]:
3 3
Length: 1, dtype: int64
# One may specify either a number of rows:
In [3]: example_series.sample(n=3)
Out[3]:
2 2
1 1
0 0
Length: 3, dtype: int64
# Or a fraction of the rows:
In [4]: example_series.sample(frac=0.5)
Out[4]:
1 1
5 5
3 3
Length: 3, dtype: int64
# weights are accepted.
In [5]: example_weights = [0, 0, 0.2, 0.2, 0.2, 0.4]
In [6]: example_series.sample(n=3, weights=example_weights)
Out[6]:
2 2
4 4
3 3
Length: 3, dtype: int64
# weights will also be normalized if they do not sum to one,
# and missing values will be treated as zeros.
In [7]: example_weights2 = [0.5, 0, 0, 0, None, np.nan]
In [8]: example_series.sample(n=1, weights=example_weights2)
Out[8]:
0 0
Length: 1, dtype: int64
当应用于 DataFrame 时,可以传入列名以指定从行中抽样时的抽样权重。
In [9]: df = pd.DataFrame({"col1": [9, 8, 7, 6], "weight_column": [0.5, 0.4, 0.1, 0]})
In [10]: df.sample(n=3, weights="weight_column")
Out[10]:
col1 weight_column
0 9 0.5
1 8 0.4
2 7 0.1
[3 rows x 2 columns]
字符串方法增强功能#
延续 v0.16.0 的改进,以下增强功能使字符串操作更简便,并与标准 Python 字符串操作更一致。
为
Index
添加了StringMethods
(.str
访问器)(GH 9068)`.str` 访问器现在可用于
Series
和Index
。In [11]: idx = pd.Index([" jack", "jill ", " jesse ", "frank"]) In [12]: idx.str.strip() Out[12]: Index(['jack', 'jill', 'jesse', 'frank'], dtype='object')
`Index` 上的 `.str` 访问器的一个特殊情况是,如果字符串方法返回
bool
,`.str` 访问器将返回np.array
而不是布尔Index
(GH 8875)。这使得以下表达式能够自然地工作In [13]: idx = pd.Index(["a1", "a2", "b1", "b2"]) In [14]: s = pd.Series(range(4), index=idx) In [15]: s Out[15]: a1 0 a2 1 b1 2 b2 3 Length: 4, dtype: int64 In [16]: idx.str.startswith("a") Out[16]: array([ True, True, False, False]) In [17]: s[s.index.str.startswith("a")] Out[17]: a1 0 a2 1 Length: 2, dtype: int64
以下新方法可通过 `.str` 访问器访问,以将函数应用于每个值。(GH 9766, GH 9773, GH 10031, GH 10045, GH 10052)
方法
capitalize()
swapcase()
normalize()
partition()
rpartition()
index()
rindex()
translate()
`split` 现在接受
expand
关键字来指定是否扩展维度。return_type
已弃用。(GH 9847)In [18]: s = pd.Series(["a,b", "a,c", "b,c"]) # return Series In [19]: s.str.split(",") Out[19]: 0 [a, b] 1 [a, c] 2 [b, c] Length: 3, dtype: object # return DataFrame In [20]: s.str.split(",", expand=True) Out[20]: 0 1 0 a b 1 a c 2 b c [3 rows x 2 columns] In [21]: idx = pd.Index(["a,b", "a,c", "b,c"]) # return Index In [22]: idx.str.split(",") Out[22]: Index([['a', 'b'], ['a', 'c'], ['b', 'c']], dtype='object') # return MultiIndex In [23]: idx.str.split(",", expand=True) Out[23]: MultiIndex([('a', 'b'), ('a', 'c'), ('b', 'c')], )
改进了
Index.str
的extract
和get_dummies
方法(GH 9980)
其他增强功能#
现在支持
BusinessHour
偏移量,默认情况下它表示BusinessDay
从 09:00 到 17:00 的工作时间。详见 此处。(GH 7905)In [24]: pd.Timestamp("2014-08-01 09:00") + pd.tseries.offsets.BusinessHour() Out[24]: Timestamp('2014-08-01 10:00:00') In [25]: pd.Timestamp("2014-08-01 07:00") + pd.tseries.offsets.BusinessHour() Out[25]: Timestamp('2014-08-01 10:00:00') In [26]: pd.Timestamp("2014-08-01 16:30") + pd.tseries.offsets.BusinessHour() Out[26]: Timestamp('2014-08-04 09:30:00')
DataFrame.diff
现在接受一个axis
参数,用于确定差分的方向(GH 9727)允许
clip
、clip_lower
和clip_upper
接受类数组参数作为阈值(这是 0.11.0 的一个回归)。这些方法现在有一个axis
参数,用于确定 Series 或 DataFrame 如何与阈值对齐。(GH 6966)DataFrame.mask()
和Series.mask()
现在支持与where
相同的关键字(GH 8801)drop
函数现在可以接受errors
关键字,以抑制当目标数据中不存在任何标签时引发的ValueError
。(GH 6736)In [27]: df = pd.DataFrame(np.random.randn(3, 3), columns=["A", "B", "C"]) In [28]: df.drop(["A", "X"], axis=1, errors="ignore") Out[28]: B C 0 -0.706771 -1.039575 1 -0.424972 0.567020 2 -1.087401 -0.673690 [3 rows x 2 columns]
添加了使用破折号分隔年份和季度的支持,例如 2014-Q1。(GH 9688)
允许使用
astype(str)
将数据类型为datetime64
或timedelta64
的值转换为字符串(GH 9757)get_dummies
函数现在接受sparse
关键字。如果设置为True
,返回的DataFrame
将是稀疏的,例如SparseDataFrame
。(GH 8823)Period
现在接受datetime64
作为值输入。(GH 9054)允许在时间定义缺少前导零时进行 timedelta 字符串转换,例如
0:00:00
与00:00:00
。(GH 9570)允许
Panel.shift
与axis='items'
一起使用(GH 9890)现在,如果
DataFrame
具有MultiIndex
,则尝试写入 Excel 文件将引发NotImplementedError
,而不是写入损坏的 Excel 文件。(GH 9794)允许
Categorical.add_categories
接受Series
或np.array
。(GH 9927)从
__dir__
动态添加/删除str/dt/cat
访问器。(GH 9910)添加
normalize
作为dt
访问器方法。(GH 10047)DataFrame
和Series
现在具有_constructor_expanddim
属性,作为可覆盖的更高维度数据构造函数。这应仅在确实需要时使用,详见 此处pd.lib.infer_dtype
在 Python 3 中现在会在适当的时候返回'bytes'
。(GH 10032)
API 变更#
当向
df.plot( ..., ax=ax)
传入 `ax` 时,sharex
关键字参数现在将默认为False
。结果是 x 轴标签和 x 轴刻度标签的可见性将不再改变。您需要自行在图中的正确轴上进行设置,或明确设置sharex=True
(但这会改变图中所有轴的可见性,而不仅仅是传入的那个轴!)。如果 pandas 自行创建子图(例如,没有传入 `ax` 关键字参数),则默认仍为sharex=True
并应用可见性更改。默认情况下,
read_csv
和read_table
现在将尝试根据文件扩展名推断压缩类型。设置compression=None
以恢复之前的行为(不解压)。(GH 9770)
弃用#
Series.str.split
的return_type
关键字已移除,取而代之的是expand
(GH 9847)
索引表示#
Index
及其子类的字符串表示现在已统一。如果值较少,它们将显示为单行;如果值很多(但少于 display.max_seq_items
),则显示为多行换行;如果项目过多(> display.max_seq_items
),则显示为截断格式(数据的开头和结尾)。MultiIndex
的格式保持不变(多行换行显示)。显示宽度响应 display.max_seq_items
选项,其默认值为 100。(GH 6482)
旧行为
In [2]: pd.Index(range(4), name='foo')
Out[2]: Int64Index([0, 1, 2, 3], dtype='int64')
In [3]: pd.Index(range(104), name='foo')
Out[3]: Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...], dtype='int64')
In [4]: pd.date_range('20130101', periods=4, name='foo', tz='US/Eastern')
Out[4]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-01-01 00:00:00-05:00, ..., 2013-01-04 00:00:00-05:00]
Length: 4, Freq: D, Timezone: US/Eastern
In [5]: pd.date_range('20130101', periods=104, name='foo', tz='US/Eastern')
Out[5]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-01-01 00:00:00-05:00, ..., 2013-04-14 00:00:00-04:00]
Length: 104, Freq: D, Timezone: US/Eastern
新行为
In [29]: pd.set_option("display.width", 80)
In [30]: pd.Index(range(4), name="foo")
Out[30]: RangeIndex(start=0, stop=4, step=1, name='foo')
In [31]: pd.Index(range(30), name="foo")
Out[31]: RangeIndex(start=0, stop=30, step=1, name='foo')
In [32]: pd.Index(range(104), name="foo")
Out[32]: RangeIndex(start=0, stop=104, step=1, name='foo')
In [33]: pd.CategoricalIndex(["a", "bb", "ccc", "dddd"], ordered=True, name="foobar")
Out[33]: CategoricalIndex(['a', 'bb', 'ccc', 'dddd'], categories=['a', 'bb', 'ccc', 'dddd'], ordered=True, dtype='category', name='foobar')
In [34]: pd.CategoricalIndex(["a", "bb", "ccc", "dddd"] * 10, ordered=True, name="foobar")
Out[34]:
CategoricalIndex(['a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a',
'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a', 'bb',
'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc',
'dddd', 'a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd',
'a', 'bb', 'ccc', 'dddd'],
categories=['a', 'bb', 'ccc', 'dddd'], ordered=True, dtype='category', name='foobar')
In [35]: pd.CategoricalIndex(["a", "bb", "ccc", "dddd"] * 100, ordered=True, name="foobar")
Out[35]:
CategoricalIndex(['a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a',
'bb',
...
'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc',
'dddd'],
categories=['a', 'bb', 'ccc', 'dddd'], ordered=True, dtype='category', name='foobar', length=400)
In [36]: pd.date_range("20130101", periods=4, name="foo", tz="US/Eastern")
Out[36]:
DatetimeIndex(['2013-01-01 00:00:00-05:00', '2013-01-02 00:00:00-05:00',
'2013-01-03 00:00:00-05:00', '2013-01-04 00:00:00-05:00'],
dtype='datetime64[ns, US/Eastern]', name='foo', freq='D')
In [37]: pd.date_range("20130101", periods=25, freq="D")
Out[37]:
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
'2013-01-05', '2013-01-06', '2013-01-07', '2013-01-08',
'2013-01-09', '2013-01-10', '2013-01-11', '2013-01-12',
'2013-01-13', '2013-01-14', '2013-01-15', '2013-01-16',
'2013-01-17', '2013-01-18', '2013-01-19', '2013-01-20',
'2013-01-21', '2013-01-22', '2013-01-23', '2013-01-24',
'2013-01-25'],
dtype='datetime64[ns]', freq='D')
In [38]: pd.date_range("20130101", periods=104, name="foo", tz="US/Eastern")
Out[38]:
DatetimeIndex(['2013-01-01 00:00:00-05:00', '2013-01-02 00:00:00-05:00',
'2013-01-03 00:00:00-05:00', '2013-01-04 00:00:00-05:00',
'2013-01-05 00:00:00-05:00', '2013-01-06 00:00:00-05:00',
'2013-01-07 00:00:00-05:00', '2013-01-08 00:00:00-05:00',
'2013-01-09 00:00:00-05:00', '2013-01-10 00:00:00-05:00',
...
'2013-04-05 00:00:00-04:00', '2013-04-06 00:00:00-04:00',
'2013-04-07 00:00:00-04:00', '2013-04-08 00:00:00-04:00',
'2013-04-09 00:00:00-04:00', '2013-04-10 00:00:00-04:00',
'2013-04-11 00:00:00-04:00', '2013-04-12 00:00:00-04:00',
'2013-04-13 00:00:00-04:00', '2013-04-14 00:00:00-04:00'],
dtype='datetime64[ns, US/Eastern]', name='foo', length=104, freq='D')
性能改进#
错误修复#
DataFrame.plot()
图例中标签显示不正确的错误已修复,现在传递label=
参数可以正常工作,且 Series 索引不再被修改。(GH 9542)JSON 序列化中的一个错误,当帧长度为零时导致段错误。(GH 9805)
read_csv
中一个错误,当缺少尾随分隔符时会导致段错误。(GH 5664)追加时保留索引名称的错误已修复(GH 9862)
scatter_matrix
绘制意外轴刻度标签的错误已修复(GH 5662)修复了
StataWriter
中的错误,该错误导致在保存时修改输入DataFrame
(GH 9795)。transform
中的一个错误,当存在空条目且使用快速聚合器时导致长度不匹配(GH 9697)equals
中的一个错误,当块顺序不同时导致假阴性(GH 9330)使用多个
pd.Grouper
进行分组时的一个错误,其中一个不是基于时间的(GH 10063)从带时区的 postgres 表读取时
read_sql_table
报错的错误已修复(GH 7139)DataFrame
切片可能无法保留元数据的错误已修复(GH 9776)HDFStore
中TimdeltaIndex
未正确序列化的错误已修复(GH 9635)TimedeltaIndex
构造函数在给定另一个TimedeltaIndex
作为数据时忽略name
的错误已修复(GH 10025)。DataFrameFormatter._get_formatted_index
未将max_colwidth
应用于DataFrame
索引的错误已修复(GH 7856).loc
处理只读 ndarray 数据源的错误已修复(GH 10043)groupby.apply()
中的一个错误,当传入的用户定义函数(对所有输入)只返回None
时会引发错误(GH 9685)在 pytables 测试中始终使用临时文件(GH 9992)
DataFrame.plot(kind="hist")
中一个错误,当DataFrame
包含非数值列时导致TypeError
(GH 9853)重复绘制带有
DatetimeIndex
的DataFrame
时可能引发TypeError
的错误已修复(GH 9852)setup.py
中的一个错误,该错误允许不兼容的 cython 版本进行构建(GH 9827)绘制
secondary_y
时错误地将right_ax
属性递归地附加到次要轴的错误已修复(GH 9861)Series.quantile
处理空Datetime
或Timedelta
类型 Series 的错误已修复(GH 9675)where
中的一个错误,当需要向上转型时导致结果不正确(GH 9731)FloatArrayFormatter
中的一个错误,当给定display.precision
时,显示“小”浮点数的十进制格式的决策边界偏差一个数量级(GH 9764)修复了
DataFrame.plot()
中的错误,当同时传递color
和style
关键字且样式字符串中没有颜色符号时会引发错误(GH 9671)在将类列表与
Index
结合时不再显示DeprecationWarning
(GH 10083)read_csv
和read_table
中一个错误,当存在空行时使用skip_rows
参数会出错(GH 9832)read_csv()
将index_col=True
解释为1
的错误已修复(GH 9798)索引相等性比较中使用
==
在 Index/MultiIndex 类型不兼容时失败的错误已修复(GH 9785)SparseDataFrame
不能将nan
作为列名的错误已修复(GH 8822)to_msgpack
和read_msgpack
zlib 和 blosc 压缩支持中的错误已修复(GH 9783)如果按
TimeGrouper
分组,GroupBy.size
未正确附加索引名称的错误已修复(GH 9925)切片赋值中导致异常的错误,因为
length_of_indexer
返回错误的结果(GH 9995)CSV 解析器中的一个错误,导致带有初始空白符和一个非空白字符的行被跳过(GH 9710)
C CSV 解析器中的一个错误,当数据以换行符和空白符开头时导致虚假 NaN(GH 10022)
当按
Categorical
分组时,导致带有空组的元素溢出到最终组的错误(GH 9603).iloc
和.loc
在空数据帧上行为不一致的错误已修复(GH 9964)对
TimedeltaIndex
进行无效属性访问时错误地引发ValueError
而不是AttributeError
的错误已修复(GH 9680)类别数据与不在类别中的标量进行不等比较时的错误(例如
Series(Categorical(list("abc"), ordered=True)) > "d"
)。以前对所有元素返回False
,现在引发TypeError
。相等性比较现在对==
返回False
,对!=
返回True
。(GH 9848)当右侧是一个字典时,DataFrame
__setitem__
中的错误已修复(GH 9874)当 dtype 为
datetime64/timedelta64
但其他 dtype 不是时,where
中的错误已修复(GH 9804)MultiIndex.sortlevel()
导致 unicode 级别名称中断的错误已修复(GH 9856)groupby.transform
错误地强制输出数据类型与输入数据类型匹配的错误已修复(GH 9807)DataFrame
构造函数中一个错误,当columns
参数设置且data
为空列表时出错(GH 9939)条形图中使用
log=True
时,如果所有值都小于 1 则引发TypeError
的错误已修复(GH 9905)水平条形图忽略
log=True
的错误已修复(GH 9905)包含
Decimal
类型值的 DataFrame 被另一个Decimal
除时会引发错误的错误已修复(GH 9787)使用 DataFrames 的
asfreq
会移除索引名称的错误已修复(GH 9885)当重新采样 BM/BQ 时导致额外索引点的错误已修复(GH 9756)
将
AbstractHolidayCalendar
中的缓存更改为实例级别,而不是类级别,因为后者可能导致意外行为。(GH 9552)修复了 MultiIndexed 数据帧的 LaTeX 输出(GH 9778)
使用
DataFrame.loc
设置空范围时导致异常的错误已修复(GH 9596)在现有轴网格中添加新绘图时,隐藏带子图和共享轴的刻度标签的错误已修复(GH 9158)
按分类变量分组时,
transform
和filter
中的错误已修复(GH 9921)当组的数量和数据类型与输入索引相同时,
transform
中的错误已修复(GH 9700)Google BigQuery 连接器现在按方法导入依赖项。(GH 9713)
更新了 BigQuery 连接器,不再使用已弃用的
oauth2client.tools.run()
(GH 8327)子类化
DataFrame
中的错误。切片或子集化时可能无法返回正确的类。(GH 9632).median()
中非浮点型空值未正确处理的错误已修复(GH 10040)Series.fillna() 中的一个错误,当给定可转换为数字的字符串时会引发错误(GH 10092)
贡献者#
共有 58 人为本次发布贡献了补丁。名字旁带有“+”的人是首次贡献补丁。
Alfonso MHC +
Andy Hayden
Artemy Kolchinsky
Chris Gilmer +
Chris Grinolds +
Dan Birken
David BROCHART +
David Hirschfeld +
David Stephens
Dr. Leo +
Evan Wright +
Frans van Dunné +
Hatem Nassrat +
Henning Sperr +
Hugo Herter +
Jan Schulz
Jeff Blackburne +
Jeff Reback
Jim Crist +
Jonas Abernot +
Joris Van den Bossche
Kerby Shedden
Leo Razoumov +
Manuel Riel +
Mortada Mehyar
Nick Burns +
Nick Eubank +
Olivier Grisel
Phillip Cloud
Pietro Battiston
Roy Hyunjin Han
Sam Zhang +
Scott Sanderson +
Sinhrks +
Stephan Hoyer
Tiago Antao
Tom Ajamian +
Tom Augspurger
Tomaz Berisa +
Vikram Shirgur +
Vladimir Filimonov
William Hogman +
Yasin A +
Younggun Kim +
behzad nouri
dsm054
floydsoft +
flying-sheep +
gfr +
jnmclarty
jreback
ksanghai +
lucas +
mschmohl +
ptype +
rockg
scls19fr +
sinhrks